1999-04-16 01:35:26 +00:00
/* Symbol table lookup for the GNU debugger, GDB.
2002-01-17 22:15:18 +00:00
Copyright 1986 , 1987 , 1988 , 1989 , 1990 , 1991 , 1992 , 1993 , 1994 ,
1995 , 1996 , 1997 , 1998 , 1999 , 2000 , 2001 , 2002 Free Software
Foundation , Inc .
1999-04-16 01:35:26 +00:00
1999-07-07 20:19:36 +00:00
This file is part of GDB .
1999-04-16 01:35:26 +00:00
1999-07-07 20:19:36 +00:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
1999-04-16 01:35:26 +00:00
1999-07-07 20:19:36 +00:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
1999-04-16 01:35:26 +00:00
1999-07-07 20:19:36 +00:00
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 ,
Boston , MA 02111 - 1307 , USA . */
1999-04-16 01:35:26 +00:00
# include "defs.h"
# include "symtab.h"
# include "gdbtypes.h"
# include "gdbcore.h"
# include "frame.h"
# include "target.h"
# include "value.h"
# include "symfile.h"
# include "objfiles.h"
# include "gdbcmd.h"
# include "call-cmds.h"
2000-04-04 02:08:52 +00:00
# include "gdb_regex.h"
1999-04-16 01:35:26 +00:00
# include "expression.h"
# include "language.h"
# include "demangle.h"
# include "inferior.h"
2000-11-30 Fernando Nasser <fnasser@redhat.com>
* linespec.h: New file. Declarations for linespec.c.
* linespec.c, alpha-tdep.c, breakpoint.c, parse.c, source.c,
symtab.c, tracepoint.c: Include the above.
* completer.c: New file. Line completion stuff for GDB.
(get_gdb_completer_word_break_characters,
get_gdb_completer_quote_characters): New functions. Accessors for
useful completer internal data.
(filename_completer, line_completion_function, skip_quoted): Moved
here from top.c.
* completer.h: New file. Declarations for the above.
* linespec.c (decode_line_1): Use
get_gdb_completer_word_break_characters and
get_gdb_completer_quote_characters.
* top.c: Include completer.h.
(filename_completer, line_completion_function, skip_quoted):
Moved to completer.c.
* corefile.c, exec.c, source.c, symfile.c, linespec.c: Include
completer.h.
* Makefile.in (SFILES): Add completer.c.
(COMMON_OBS): Add completer.o.
(completer.o): New target.
(linespec.o, alpha-tdep.o, breakpoint.o, parse.o, source.o,
symtab.o, tracepoint.o): Add linespec.h to dependencies list.
(corefile.o, exec.o, source.o, symfile.o, linespec.o): Add completer.h
to dependencies list.
2000-12-01 00:43:47 +00:00
# include "linespec.h"
2002-09-20 14:58:59 +00:00
# include "source.h"
2001-05-06 06:07:20 +00:00
# include "filenames.h" /* for FILENAME_CMP */
1999-04-16 01:35:26 +00:00
2002-07-29 Andrew Cagney <ac131313@redhat.com>
* gdb_obstack.h: New file.
* symtab.h: Include "gdb_obstack.h" instead of "obstack.h".
(obstack_chunk_alloc, obstack_chunk_free): Delete macros.
* objfiles.h: Include "gdb_obstack.h".
* Makefile.in (gdb_obstack_h): Define.
(symtab_h): Add $(gdb_obstack_h).
(objfiles_h): Add $(gdb_obstack_h).
* objfiles.c: Include "gdb_obstack.h" instead of "obstack.h".
* macrotab.c, cp-valprint.c, dbxread.c: Ditto.
* ch-typeprint.c, ch-valprint.c, dstread.c: Ditto.
* macroexp.c, p-typeprint.c, stabsread.c: Ditto.
* symtab.c, f-typeprint.c, mdebugread.c: Ditto.
* p-valprint.c, symmisc.c, typeprint.c: Ditto.
* symfile.c, coffread.c, c-typeprint.c: Ditto.
* buildsym.c, bcache.c, ada-typeprint.c: Ditto.
* Makefile.in (bcache.o): Update dependencies.
(buildsym.o, c-typeprint.o, ch-typeprint.o): Ditto.
(ch-valprint.o, coffread.o, cp-valprint.o): Ditto.
(dbxread.o, dstread.o, f-typeprint.o): Ditto.
(objfiles.o, p-typeprint.o, p-valprint.o): Ditto.
(stabsread.o, symfile.o, symmisc.o): Ditto.
(symtab.o, typeprint.o, macroexp.o): Ditto.
(macrotab.o, mdebugread.o): Ditto.
(f_lang_h, coff_sym_h, coff_symconst_h): Define.
(coff_ecoff_h, aout_aout64_h): Define.
(aout_stabs_gnu_h, libaout_h): Define.
2002-07-29 22:55:26 +00:00
# include "gdb_obstack.h"
1999-04-16 01:35:26 +00:00
# include <sys/types.h>
# include <fcntl.h>
# include "gdb_string.h"
# include "gdb_stat.h"
# include <ctype.h>
(Changes from Daniel Berlin, with revisions by Jim Blandy.)
Abstract out operations specific to particular C++ ABI's, and
invoke them through a function table. This removes the C++ ABI
dependencies scattered throughout the code, and allows us to
cleanly add support for new C++ ABI's.
* cp-abi.h, cp-abi.h, gnu-v2-abi.c, hpacc-abi.c: New files.
* c-typeprint.c, c-valprint.c, dbxread.c, eval.c, gdbtypes.c,
jv-typeprint.c, linespec.c, symtab.c, typeprint.c, valops.c:
#include "cp-abi.h". These files all use functions now declared
there.
* symtab.h (OPNAME_PREFIX_P, VTBL_PREFIX_P, DESTRUCTOR_PREFIX_P):
Deleted. These services are now provided by functions declared in
cp-abi.h.
* value.h (value_rtti_type, value_virtual_fn_field): Same.
* values.c (value_virtual_fn_field): Same, for this definition.
* valops.c (value_rtti_type): Same.
* c-typeprint.c (c_type_print_base): Use the functions from
"cp-abi.h", instead of the old macros, or hard-coded ABI-specific
tests.
* dbxread.c (record_minimal_symbol): Same.
* gdbtypes.c (get_destructor_fn_field, virtual_base_index,
virtual_base_index_skip_primaries): Same.
* jv-typeprint.c (java_type_print_base): Same.
* linespec.c (find_methods, decode_line_1): Same.
* symtab.c (gdb_mangle_name): Same.
* Makefile.in (SFILES): Add the new .c files mentioned above.
(cp_abi_h): New variable.
(COMMON_OBS): Add gnu-v2-abi.o, hpacc-abi.o, and cp-abi.o.
(cp-abi.o, gnu-v2-abi.o, hpacc-abi.o): New targets.
(c-typeprint.o, c-valprint.o, dbxread.o, eval.o, gdbtypes.o,
jv-typeprint.o, symtab.o, linespec.o, typeprint.o, valops.o): Add
dependency on $(cp_abi_h).
2001-04-27 00:19:09 +00:00
# include "cp-abi.h"
1999-04-16 01:35:26 +00:00
/* Prototypes for local functions */
2000-05-28 01:12:42 +00:00
static void completion_list_add_name ( char * , char * , int , char * , char * ) ;
1999-04-16 01:35:26 +00:00
2000-05-28 01:12:42 +00:00
static void rbreak_command ( char * , int ) ;
1999-04-16 01:35:26 +00:00
2000-05-28 01:12:42 +00:00
static void types_info ( char * , int ) ;
1999-04-16 01:35:26 +00:00
2000-05-28 01:12:42 +00:00
static void functions_info ( char * , int ) ;
1999-04-16 01:35:26 +00:00
2000-05-28 01:12:42 +00:00
static void variables_info ( char * , int ) ;
1999-04-16 01:35:26 +00:00
2000-05-28 01:12:42 +00:00
static void sources_info ( char * , int ) ;
1999-04-16 01:35:26 +00:00
2000-05-28 01:12:42 +00:00
static void output_source_filename ( char * , int * ) ;
1999-04-16 01:35:26 +00:00
2000-05-28 01:12:42 +00:00
static int find_line_common ( struct linetable * , int , int * ) ;
1999-04-16 01:35:26 +00:00
2000-11-10 23:02:56 +00:00
/* This one is used by linespec.c */
char * operator_chars ( char * p , char * * end ) ;
2000-06-14 00:59:07 +00:00
static struct partial_symbol * lookup_partial_symbol ( struct partial_symtab * ,
const char * , int ,
namespace_enum ) ;
1999-04-16 01:35:26 +00:00
2002-03-22 18:57:08 +00:00
static struct symbol * lookup_symbol_aux ( const char * name ,
const char * mangled_name ,
const struct block * block ,
const namespace_enum namespace ,
int * is_a_field_of_this ,
struct symtab * * symtab ) ;
2000-10-12 16:53:06 +00:00
2002-12-05 21:26:57 +00:00
static
struct symbol * lookup_symbol_aux_local ( const char * name ,
const char * mangled_name ,
const struct block * block ,
const namespace_enum namespace ,
struct symtab * * symtab ,
const struct block * * static_block ) ;
2002-11-05 20:33:01 +00:00
2002-12-05 21:07:49 +00:00
static
struct symbol * lookup_symbol_aux_block ( const char * name ,
const char * mangled_name ,
const struct block * block ,
const namespace_enum namespace ,
struct symtab * * symtab ) ;
2002-11-05 20:33:01 +00:00
static
struct symbol * lookup_symbol_aux_symtabs ( int block_index ,
const char * name ,
const char * mangled_name ,
const namespace_enum namespace ,
struct symtab * * symtab ) ;
static
struct symbol * lookup_symbol_aux_psymtabs ( int block_index ,
const char * name ,
const char * mangled_name ,
const namespace_enum namespace ,
struct symtab * * symtab ) ;
2000-10-12 16:53:06 +00:00
2002-12-04 22:54:59 +00:00
static
struct symbol * lookup_symbol_aux_minsyms ( const char * name ,
const char * mangled_name ,
const namespace_enum namespace ,
int * is_a_field_of_this ,
struct symtab * * symtab ,
int * force_return ) ;
2000-05-28 01:12:42 +00:00
static struct symbol * find_active_alias ( struct symbol * sym , CORE_ADDR addr ) ;
1999-04-16 01:35:26 +00:00
/* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */
/* Signals the presence of objects compiled by HP compilers */
int hp_som_som_object_present = 0 ;
2000-05-28 01:12:42 +00:00
static void fixup_section ( struct general_symbol_info * , struct objfile * ) ;
1999-04-16 01:35:26 +00:00
2000-05-28 01:12:42 +00:00
static int file_matches ( char * , char * * , int ) ;
1999-04-16 01:35:26 +00:00
2000-05-28 01:12:42 +00:00
static void print_symbol_info ( namespace_enum ,
struct symtab * , struct symbol * , int , char * ) ;
1999-04-16 01:35:26 +00:00
2000-05-28 01:12:42 +00:00
static void print_msymbol_info ( struct minimal_symbol * ) ;
1999-04-16 01:35:26 +00:00
2000-05-28 01:12:42 +00:00
static void symtab_symbol_info ( char * , namespace_enum , int ) ;
1999-04-16 01:35:26 +00:00
2000-05-28 01:12:42 +00:00
static void overload_list_add_symbol ( struct symbol * sym , char * oload_name ) ;
1999-05-25 18:09:09 +00:00
2000-05-28 01:12:42 +00:00
void _initialize_symtab ( void ) ;
1999-04-16 01:35:26 +00:00
/* */
/* The single non-language-specific builtin type */
struct type * builtin_type_error ;
/* Block in which the most recently searched-for symbol was found.
Might be better to make this a parameter to lookup_symbol and
value_of_this . */
const struct block * block_found ;
/* Check for a symtab of a specific name; first in symtabs, then in
psymtabs . * If * there is no ' / ' in the name , a match after a ' / '
in the symtab filename will also work . */
2001-10-12 03:38:12 +00:00
struct symtab *
lookup_symtab ( const char * name )
1999-04-16 01:35:26 +00:00
{
register struct symtab * s ;
register struct partial_symtab * ps ;
register struct objfile * objfile ;
2001-12-21 22:32:37 +00:00
char * real_path = NULL ;
2002-04-05 16:42:04 +00:00
char * full_path = NULL ;
2001-12-21 22:32:37 +00:00
/* Here we are interested in canonicalizing an absolute path, not
absolutizing a relative path . */
if ( IS_ABSOLUTE_PATH ( name ) )
2002-04-05 16:42:04 +00:00
{
full_path = xfullpath ( name ) ;
make_cleanup ( xfree , full_path ) ;
real_path = gdb_realpath ( name ) ;
make_cleanup ( xfree , real_path ) ;
}
1999-04-16 01:35:26 +00:00
1999-07-07 20:19:36 +00:00
got_symtab :
1999-04-16 01:35:26 +00:00
/* First, search for an exact match */
ALL_SYMTABS ( objfile , s )
2001-12-21 22:32:37 +00:00
{
2001-05-06 06:07:20 +00:00
if ( FILENAME_CMP ( name , s - > filename ) = = 0 )
2001-12-21 22:32:37 +00:00
{
return s ;
}
2002-04-05 16:42:04 +00:00
2001-12-21 22:32:37 +00:00
/* If the user gave us an absolute path, try to find the file in
this symtab and use its absolute path . */
2002-04-05 16:42:04 +00:00
if ( full_path ! = NULL )
{
const char * fp = symtab_to_filename ( s ) ;
if ( FILENAME_CMP ( full_path , fp ) = = 0 )
{
return s ;
}
}
2001-12-21 22:32:37 +00:00
if ( real_path ! = NULL )
{
2002-04-06 18:28:20 +00:00
char * rp = gdb_realpath ( symtab_to_filename ( s ) ) ;
2002-04-05 16:42:04 +00:00
make_cleanup ( xfree , rp ) ;
2001-12-21 22:32:37 +00:00
if ( FILENAME_CMP ( real_path , rp ) = = 0 )
{
return s ;
}
}
}
1999-04-16 01:35:26 +00:00
/* Now, search for a matching tail (only if name doesn't have any dirs) */
2001-05-14 18:49:54 +00:00
if ( lbasename ( name ) = = name )
1999-04-16 01:35:26 +00:00
ALL_SYMTABS ( objfile , s )
1999-07-07 20:19:36 +00:00
{
2001-06-13 18:30:07 +00:00
if ( FILENAME_CMP ( lbasename ( s - > filename ) , name ) = = 0 )
1999-07-07 20:19:36 +00:00
return s ;
}
1999-04-16 01:35:26 +00:00
/* Same search rules as above apply here, but now we look thru the
psymtabs . */
ps = lookup_partial_symtab ( name ) ;
if ( ! ps )
return ( NULL ) ;
1999-07-07 20:19:36 +00:00
if ( ps - > readin )
1999-04-16 01:35:26 +00:00
error ( " Internal: readin %s pst for `%s' found when no symtab found. " ,
1999-07-07 20:19:36 +00:00
ps - > filename , name ) ;
1999-04-16 01:35:26 +00:00
s = PSYMTAB_TO_SYMTAB ( ps ) ;
if ( s )
return s ;
/* At this point, we have located the psymtab for this file, but
the conversion to a symtab has failed . This usually happens
when we are looking up an include file . In this case ,
PSYMTAB_TO_SYMTAB doesn ' t return a symtab , even though one has
been created . So , we need to run through the symtabs again in
order to find the file .
XXX - This is a crock , and should be fixed inside of the the
symbol parsing routines . */
goto got_symtab ;
}
/* Lookup the partial symbol table of a source file named NAME.
* If * there is no ' / ' in the name , a match after a ' / '
in the psymtab filename will also work . */
struct partial_symtab *
2001-06-12 15:03:04 +00:00
lookup_partial_symtab ( const char * name )
1999-04-16 01:35:26 +00:00
{
register struct partial_symtab * pst ;
register struct objfile * objfile ;
2002-04-05 16:42:04 +00:00
char * full_path = NULL ;
2001-12-21 22:32:37 +00:00
char * real_path = NULL ;
/* Here we are interested in canonicalizing an absolute path, not
absolutizing a relative path . */
if ( IS_ABSOLUTE_PATH ( name ) )
2002-04-05 16:42:04 +00:00
{
full_path = xfullpath ( name ) ;
make_cleanup ( xfree , full_path ) ;
real_path = gdb_realpath ( name ) ;
make_cleanup ( xfree , real_path ) ;
}
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
ALL_PSYMTABS ( objfile , pst )
1999-07-07 20:19:36 +00:00
{
2001-05-06 06:07:20 +00:00
if ( FILENAME_CMP ( name , pst - > filename ) = = 0 )
1999-07-07 20:19:36 +00:00
{
return ( pst ) ;
}
2002-04-05 16:42:04 +00:00
2001-12-21 22:32:37 +00:00
/* If the user gave us an absolute path, try to find the file in
this symtab and use its absolute path . */
2002-04-05 16:42:04 +00:00
if ( full_path ! = NULL )
2001-12-21 22:32:37 +00:00
{
if ( pst - > fullname = = NULL )
source_full_path_of ( pst - > filename , & pst - > fullname ) ;
if ( pst - > fullname ! = NULL
2002-04-05 16:42:04 +00:00
& & FILENAME_CMP ( full_path , pst - > fullname ) = = 0 )
2001-12-21 22:32:37 +00:00
{
return pst ;
}
}
1999-04-16 01:35:26 +00:00
2002-04-05 16:42:04 +00:00
if ( real_path ! = NULL )
{
char * rp = NULL ;
if ( pst - > fullname = = NULL )
source_full_path_of ( pst - > filename , & pst - > fullname ) ;
if ( pst - > fullname ! = NULL )
{
rp = gdb_realpath ( pst - > fullname ) ;
make_cleanup ( xfree , rp ) ;
}
if ( rp ! = NULL & & FILENAME_CMP ( real_path , rp ) = = 0 )
{
return pst ;
}
}
}
2001-12-21 22:32:37 +00:00
1999-04-16 01:35:26 +00:00
/* Now, search for a matching tail (only if name doesn't have any dirs) */
2001-05-14 18:49:54 +00:00
if ( lbasename ( name ) = = name )
1999-04-16 01:35:26 +00:00
ALL_PSYMTABS ( objfile , pst )
1999-07-07 20:19:36 +00:00
{
2001-06-13 18:30:07 +00:00
if ( FILENAME_CMP ( lbasename ( pst - > filename ) , name ) = = 0 )
1999-07-07 20:19:36 +00:00
return ( pst ) ;
}
1999-04-16 01:35:26 +00:00
return ( NULL ) ;
}
/* Mangle a GDB method stub type. This actually reassembles the pieces of the
full method name , which consist of the class name ( from T ) , the unadorned
method name from METHOD_ID , and the signature for the specific overload ,
specified by SIGNATURE_ID . Note that this function is g + + specific . */
char *
2000-07-30 01:48:28 +00:00
gdb_mangle_name ( struct type * type , int method_id , int signature_id )
1999-04-16 01:35:26 +00:00
{
int mangled_name_len ;
char * mangled_name ;
struct fn_field * f = TYPE_FN_FIELDLIST1 ( type , method_id ) ;
struct fn_field * method = & f [ signature_id ] ;
char * field_name = TYPE_FN_FIELDLIST_NAME ( type , method_id ) ;
char * physname = TYPE_FN_FIELD_PHYSNAME ( f , signature_id ) ;
char * newname = type_name_no_tag ( type ) ;
/* Does the form of physname indicate that it is the full mangled name
of a constructor ( not just the args ) ? */
int is_full_physname_constructor ;
int is_constructor ;
(Changes from Daniel Berlin, with revisions by Jim Blandy.)
Abstract out operations specific to particular C++ ABI's, and
invoke them through a function table. This removes the C++ ABI
dependencies scattered throughout the code, and allows us to
cleanly add support for new C++ ABI's.
* cp-abi.h, cp-abi.h, gnu-v2-abi.c, hpacc-abi.c: New files.
* c-typeprint.c, c-valprint.c, dbxread.c, eval.c, gdbtypes.c,
jv-typeprint.c, linespec.c, symtab.c, typeprint.c, valops.c:
#include "cp-abi.h". These files all use functions now declared
there.
* symtab.h (OPNAME_PREFIX_P, VTBL_PREFIX_P, DESTRUCTOR_PREFIX_P):
Deleted. These services are now provided by functions declared in
cp-abi.h.
* value.h (value_rtti_type, value_virtual_fn_field): Same.
* values.c (value_virtual_fn_field): Same, for this definition.
* valops.c (value_rtti_type): Same.
* c-typeprint.c (c_type_print_base): Use the functions from
"cp-abi.h", instead of the old macros, or hard-coded ABI-specific
tests.
* dbxread.c (record_minimal_symbol): Same.
* gdbtypes.c (get_destructor_fn_field, virtual_base_index,
virtual_base_index_skip_primaries): Same.
* jv-typeprint.c (java_type_print_base): Same.
* linespec.c (find_methods, decode_line_1): Same.
* symtab.c (gdb_mangle_name): Same.
* Makefile.in (SFILES): Add the new .c files mentioned above.
(cp_abi_h): New variable.
(COMMON_OBS): Add gnu-v2-abi.o, hpacc-abi.o, and cp-abi.o.
(cp-abi.o, gnu-v2-abi.o, hpacc-abi.o): New targets.
(c-typeprint.o, c-valprint.o, dbxread.o, eval.o, gdbtypes.o,
jv-typeprint.o, symtab.o, linespec.o, typeprint.o, valops.o): Add
dependency on $(cp_abi_h).
2001-04-27 00:19:09 +00:00
int is_destructor = is_destructor_name ( physname ) ;
1999-04-16 01:35:26 +00:00
/* Need a new type prefix. */
char * const_prefix = method - > is_const ? " C " : " " ;
char * volatile_prefix = method - > is_volatile ? " V " : " " ;
char buf [ 20 ] ;
int len = ( newname = = NULL ? 0 : strlen ( newname ) ) ;
2002-02-27 18:22:24 +00:00
/* Nothing to do if physname already contains a fully mangled v3 abi name
or an operator name . */
if ( ( physname [ 0 ] = = ' _ ' & & physname [ 1 ] = = ' Z ' )
| | is_operator_name ( field_name ) )
2000-10-12 19:34:27 +00:00
return xstrdup ( physname ) ;
(Changes from Daniel Berlin, with revisions by Jim Blandy.)
Abstract out operations specific to particular C++ ABI's, and
invoke them through a function table. This removes the C++ ABI
dependencies scattered throughout the code, and allows us to
cleanly add support for new C++ ABI's.
* cp-abi.h, cp-abi.h, gnu-v2-abi.c, hpacc-abi.c: New files.
* c-typeprint.c, c-valprint.c, dbxread.c, eval.c, gdbtypes.c,
jv-typeprint.c, linespec.c, symtab.c, typeprint.c, valops.c:
#include "cp-abi.h". These files all use functions now declared
there.
* symtab.h (OPNAME_PREFIX_P, VTBL_PREFIX_P, DESTRUCTOR_PREFIX_P):
Deleted. These services are now provided by functions declared in
cp-abi.h.
* value.h (value_rtti_type, value_virtual_fn_field): Same.
* values.c (value_virtual_fn_field): Same, for this definition.
* valops.c (value_rtti_type): Same.
* c-typeprint.c (c_type_print_base): Use the functions from
"cp-abi.h", instead of the old macros, or hard-coded ABI-specific
tests.
* dbxread.c (record_minimal_symbol): Same.
* gdbtypes.c (get_destructor_fn_field, virtual_base_index,
virtual_base_index_skip_primaries): Same.
* jv-typeprint.c (java_type_print_base): Same.
* linespec.c (find_methods, decode_line_1): Same.
* symtab.c (gdb_mangle_name): Same.
* Makefile.in (SFILES): Add the new .c files mentioned above.
(cp_abi_h): New variable.
(COMMON_OBS): Add gnu-v2-abi.o, hpacc-abi.o, and cp-abi.o.
(cp-abi.o, gnu-v2-abi.o, hpacc-abi.o): New targets.
(c-typeprint.o, c-valprint.o, dbxread.o, eval.o, gdbtypes.o,
jv-typeprint.o, symtab.o, linespec.o, typeprint.o, valops.o): Add
dependency on $(cp_abi_h).
2001-04-27 00:19:09 +00:00
is_full_physname_constructor = is_constructor_name ( physname ) ;
1999-04-16 01:35:26 +00:00
is_constructor =
1999-07-07 20:19:36 +00:00
is_full_physname_constructor | | ( newname & & STREQ ( field_name , newname ) ) ;
1999-04-16 01:35:26 +00:00
if ( ! is_destructor )
1999-07-07 20:19:36 +00:00
is_destructor = ( strncmp ( physname , " __dt " , 4 ) = = 0 ) ;
1999-04-16 01:35:26 +00:00
if ( is_destructor | | is_full_physname_constructor )
{
1999-07-07 20:19:36 +00:00
mangled_name = ( char * ) xmalloc ( strlen ( physname ) + 1 ) ;
strcpy ( mangled_name , physname ) ;
1999-04-16 01:35:26 +00:00
return mangled_name ;
}
if ( len = = 0 )
{
sprintf ( buf , " __%s%s " , const_prefix , volatile_prefix ) ;
}
else if ( physname [ 0 ] = = ' t ' | | physname [ 0 ] = = ' Q ' )
{
/* The physname for template and qualified methods already includes
1999-07-07 20:19:36 +00:00
the class name . */
1999-04-16 01:35:26 +00:00
sprintf ( buf , " __%s%s " , const_prefix , volatile_prefix ) ;
newname = NULL ;
len = 0 ;
}
else
{
sprintf ( buf , " __%s%s%d " , const_prefix , volatile_prefix , len ) ;
}
mangled_name_len = ( ( is_constructor ? 0 : strlen ( field_name ) )
2000-10-12 19:34:27 +00:00
+ strlen ( buf ) + len + strlen ( physname ) + 1 ) ;
1999-04-16 01:35:26 +00:00
{
1999-07-07 20:19:36 +00:00
mangled_name = ( char * ) xmalloc ( mangled_name_len ) ;
1999-04-16 01:35:26 +00:00
if ( is_constructor )
mangled_name [ 0 ] = ' \0 ' ;
else
strcpy ( mangled_name , field_name ) ;
}
strcat ( mangled_name , buf ) ;
/* If the class doesn't have a name, i.e. newname NULL, then we just
mangle it using 0 for the length of the class . Thus it gets mangled
1999-07-07 20:19:36 +00:00
as something starting with ` : : ' rather than ` classname : : ' . */
1999-04-16 01:35:26 +00:00
if ( newname ! = NULL )
strcat ( mangled_name , newname ) ;
strcat ( mangled_name , physname ) ;
return ( mangled_name ) ;
}
2002-03-27 23:10:24 +00:00
2002-10-23 18:16:44 +00:00
/* Initialize the language dependent portion of a symbol
depending upon the language for the symbol . */
void
symbol_init_language_specific ( struct general_symbol_info * gsymbol ,
enum language language )
{
gsymbol - > language = language ;
if ( gsymbol - > language = = language_cplus
| | gsymbol - > language = = language_java )
{
gsymbol - > language_specific . cplus_specific . demangled_name = NULL ;
}
else if ( gsymbol - > language = = language_objc )
{
gsymbol - > language_specific . objc_specific . demangled_name = NULL ;
}
/* OBSOLETE else if (SYMBOL_LANGUAGE (symbol) == language_chill) */
/* OBSOLETE { */
/* OBSOLETE SYMBOL_CHILL_DEMANGLED_NAME (symbol) = NULL; */
/* OBSOLETE } */
else
{
memset ( & gsymbol - > language_specific , 0 ,
sizeof ( gsymbol - > language_specific ) ) ;
}
}
2002-03-27 23:10:24 +00:00
/* Initialize a symbol's mangled name. */
/* Try to initialize the demangled name for a symbol, based on the
language of that symbol . If the language is set to language_auto ,
it will attempt to find any demangling algorithm that works and
then set the language appropriately . If no demangling of any kind
is found , the language is set back to language_unknown , so we can
avoid doing this work again the next time we encounter the symbol .
Any required space to store the name is obtained from the specified
obstack . */
void
symbol_init_demangled_name ( struct general_symbol_info * gsymbol ,
struct obstack * obstack )
{
char * mangled = gsymbol - > name ;
char * demangled = NULL ;
if ( gsymbol - > language = = language_unknown )
gsymbol - > language = language_auto ;
if ( gsymbol - > language = = language_cplus
| | gsymbol - > language = = language_auto )
{
demangled =
cplus_demangle ( gsymbol - > name , DMGL_PARAMS | DMGL_ANSI ) ;
if ( demangled ! = NULL )
{
gsymbol - > language = language_cplus ;
gsymbol - > language_specific . cplus_specific . demangled_name =
obsavestring ( demangled , strlen ( demangled ) , obstack ) ;
xfree ( demangled ) ;
}
else
{
gsymbol - > language_specific . cplus_specific . demangled_name = NULL ;
}
}
if ( gsymbol - > language = = language_java )
{
demangled =
cplus_demangle ( gsymbol - > name ,
DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA ) ;
if ( demangled ! = NULL )
{
gsymbol - > language = language_java ;
gsymbol - > language_specific . cplus_specific . demangled_name =
obsavestring ( demangled , strlen ( demangled ) , obstack ) ;
xfree ( demangled ) ;
}
else
{
gsymbol - > language_specific . cplus_specific . demangled_name = NULL ;
}
}
2002-08-01 Andrew Cagney <cagney@redhat.com>
* NEWS: Menion that CHILL has been made obsolete.
* gdbtypes.c (chill_varying_type): Make chill references obsolete.
* gdbserver/Makefile.in: Ditto.
* stabsread.c (read_range_type): Ditto.
* gdbtypes.h: Ditto.
* language.c (binop_type_check): Ditto.
(binop_result_type): Ditto.
(integral_type): Ditto.
(character_type): Ditto.
(string_type): Ditto.
(boolean_type): Ditto.
(structured_type): Ditto.
(lang_bool_type): Ditto.
(binop_type_check): Ditto.
* language.h (_LANG_chill): Ditto.
* dwarfread.c (set_cu_language): Ditto.
* dwarfread.c (CHILL_PRODUCER): Ditto.
* dwarfread.c (handle_producer): Ditto.
* expression.h (enum exp_opcode): Ditto.
* eval.c: Ditto for comments.
* typeprint.c (typedef_print) [_LANG_chill]: Ditto.
* expprint.c (print_subexp): Ditto.
(print_subexp): Ditto.
* valops.c (value_cast): Ditto.
(search_struct_field): Ditto.
* value.h (COERCE_VARYING_ARRAY): Ditto.
* symfile.c (init_filename_language_table): Ditto.
(add_psymbol_with_dem_name_to_list): Ditto.
* valarith.c (value_binop): Ditto.
(value_neg): Ditto.
* valops.c (value_slice): Ditto.
* symtab.h (union language_specific): Ditto.
(SYMBOL_INIT_LANGUAGE_SPECIFIC): Ditto.
(SYMBOL_DEMANGLED_NAME): Ditto.
(SYMBOL_CHILL_DEMANGLED_NAME): Ditto.
* defs.h (enum language): Ditto.
* symtab.c (got_symtab): Ditto.
* utils.c (fprintf_symbol_filtered): Ditto.
* ch-typeprint.c: Make file obsolete.
* ch-valprint.c: Make file obsolete.
* ch-lang.h: Make file obsolete.
* ch-exp.c: Make file obsolete.
* ch-lang.c: Make file obsolete.
* Makefile.in (FLAGS_TO_PASS): Do not pass CHILL or CHILLFLAGS or
CHILL_LIB.
(TARGET_FLAGS_TO_PASS): Ditto.
(CHILLFLAGS): Obsolete.
(CHILL): Obsolete.
(CHILL_FOR_TARGET): Obsolete.
(CHILL_LIB): Obsolete.
(SFILES): Remove ch-exp.c, ch-lang.c, ch-typeprint.c and
ch-valprint.c.
(HFILES_NO_SRCDIR): Remove ch-lang.h.
(COMMON_OBS): Remove ch-valprint.o, ch-typeprint.o, ch-exp.o and
ch-lang.o.
(ch-exp.o, ch-lang.o, ch-typeprint.o, ch-valprint.o): Delete
targets.
2002-08-01 Andrew Cagney <cagney@redhat.com>
* stabs.texinfo, gdb.texinfo, gdbint.texinfo: Obsolete references
to CHILL.
2002-08-01 Andrew Cagney <cagney@redhat.com>
* Makefile.in (TARGET_FLAGS_TO_PASS): Remove CHILLFLAGS, CHILL,
CHILL_FOR_TARGET and CHILL_LIB.
* configure.in (configdirs): Remove gdb.chill.
* configure: Regenerate.
* lib/gdb.exp: Obsolete references to chill.
* gdb.fortran/types.exp: Ditto.
* gdb.fortran/exprs.exp: Ditto.
2002-08-01 17:18:35 +00:00
#if 0
/* OBSOLETE if (demangled == NULL */
/* OBSOLETE && (gsymbol->language == language_chill */
/* OBSOLETE || gsymbol->language == language_auto)) */
/* OBSOLETE { */
/* OBSOLETE demangled = */
/* OBSOLETE chill_demangle (gsymbol->name); */
/* OBSOLETE if (demangled != NULL) */
/* OBSOLETE { */
/* OBSOLETE gsymbol->language = language_chill; */
/* OBSOLETE gsymbol->language_specific.chill_specific.demangled_name = */
/* OBSOLETE obsavestring (demangled, strlen (demangled), obstack); */
/* OBSOLETE xfree (demangled); */
/* OBSOLETE } */
/* OBSOLETE else */
/* OBSOLETE { */
/* OBSOLETE gsymbol->language_specific.chill_specific.demangled_name = NULL; */
/* OBSOLETE } */
/* OBSOLETE } */
# endif
2002-03-27 23:10:24 +00:00
}
2002-10-23 20:09:28 +00:00
/* Return the demangled name for a symbol based on the language for
that symbol . If no demangled name exists , return NULL . */
char *
symbol_demangled_name ( struct general_symbol_info * gsymbol )
{
if ( gsymbol - > language = = language_cplus
| | gsymbol - > language = = language_java )
return gsymbol - > language_specific . cplus_specific . demangled_name ;
2002-03-27 23:10:24 +00:00
2002-10-23 20:09:28 +00:00
else if ( gsymbol - > language = = language_objc )
return gsymbol - > language_specific . objc_specific . demangled_name ;
else
return NULL ;
/* OBSOLETE (SYMBOL_LANGUAGE (symbol) == language_chill */
/* OBSOLETE ? SYMBOL_CHILL_DEMANGLED_NAME (symbol) */
}
2002-10-24 21:02:53 +00:00
/* Initialize the structure fields to zero values. */
void
init_sal ( struct symtab_and_line * sal )
{
sal - > symtab = 0 ;
sal - > section = 0 ;
sal - > line = 0 ;
sal - > pc = 0 ;
sal - > end = 0 ;
}
1999-04-16 01:35:26 +00:00
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
/* Find which partial symtab on contains PC and SECTION. Return 0 if none. */
struct partial_symtab *
2000-07-30 01:48:28 +00:00
find_pc_sect_psymtab ( CORE_ADDR pc , asection * section )
1999-04-16 01:35:26 +00:00
{
register struct partial_symtab * pst ;
register struct objfile * objfile ;
2002-01-31 05:03:31 +00:00
struct minimal_symbol * msymbol ;
/* If we know that this is not a text address, return failure. This is
necessary because we loop based on texthigh and textlow , which do
not include the data ranges . */
msymbol = lookup_minimal_symbol_by_pc_section ( pc , section ) ;
if ( msymbol
& & ( msymbol - > type = = mst_data
| | msymbol - > type = = mst_bss
| | msymbol - > type = = mst_abs
| | msymbol - > type = = mst_file_data
| | msymbol - > type = = mst_file_bss ) )
return NULL ;
1999-04-16 01:35:26 +00:00
ALL_PSYMTABS ( objfile , pst )
1999-07-07 20:19:36 +00:00
{
if ( pc > = pst - > textlow & & pc < pst - > texthigh )
{
struct partial_symtab * tpst ;
/* An objfile that has its functions reordered might have
many partial symbol tables containing the PC , but
we want the partial symbol table that contains the
function containing the PC . */
if ( ! ( objfile - > flags & OBJF_REORDERED ) & &
section = = 0 ) /* can't validate section this way */
return ( pst ) ;
if ( msymbol = = NULL )
return ( pst ) ;
for ( tpst = pst ; tpst ! = NULL ; tpst = tpst - > next )
{
if ( pc > = tpst - > textlow & & pc < tpst - > texthigh )
{
struct partial_symbol * p ;
1999-04-16 01:35:26 +00:00
1999-07-07 20:19:36 +00:00
p = find_pc_sect_psymbol ( tpst , pc , section ) ;
if ( p ! = NULL
& & SYMBOL_VALUE_ADDRESS ( p )
= = SYMBOL_VALUE_ADDRESS ( msymbol ) )
return ( tpst ) ;
}
}
return ( pst ) ;
}
}
1999-04-16 01:35:26 +00:00
return ( NULL ) ;
}
/* Find which partial symtab contains PC. Return 0 if none.
Backward compatibility , no section */
struct partial_symtab *
2000-07-30 01:48:28 +00:00
find_pc_psymtab ( CORE_ADDR pc )
1999-04-16 01:35:26 +00:00
{
return find_pc_sect_psymtab ( pc , find_pc_mapped_section ( pc ) ) ;
}
/* Find which partial symbol within a psymtab matches PC and SECTION.
Return 0 if none . Check all psymtabs if PSYMTAB is 0. */
struct partial_symbol *
2000-07-30 01:48:28 +00:00
find_pc_sect_psymbol ( struct partial_symtab * psymtab , CORE_ADDR pc ,
asection * section )
1999-04-16 01:35:26 +00:00
{
struct partial_symbol * best = NULL , * p , * * pp ;
CORE_ADDR best_pc ;
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
if ( ! psymtab )
psymtab = find_pc_sect_psymtab ( pc , section ) ;
if ( ! psymtab )
return 0 ;
/* Cope with programs that start at address 0 */
best_pc = ( psymtab - > textlow ! = 0 ) ? psymtab - > textlow - 1 : 0 ;
/* Search the global symbols as well as the static symbols, so that
find_pc_partial_function doesn ' t use a minimal symbol and thus
cache a bad endaddr . */
for ( pp = psymtab - > objfile - > global_psymbols . list + psymtab - > globals_offset ;
1999-07-07 20:19:36 +00:00
( pp - ( psymtab - > objfile - > global_psymbols . list + psymtab - > globals_offset )
< psymtab - > n_global_syms ) ;
1999-04-16 01:35:26 +00:00
pp + + )
{
p = * pp ;
if ( SYMBOL_NAMESPACE ( p ) = = VAR_NAMESPACE
& & SYMBOL_CLASS ( p ) = = LOC_BLOCK
& & pc > = SYMBOL_VALUE_ADDRESS ( p )
& & ( SYMBOL_VALUE_ADDRESS ( p ) > best_pc
| | ( psymtab - > textlow = = 0
& & best_pc = = 0 & & SYMBOL_VALUE_ADDRESS ( p ) = = 0 ) ) )
{
1999-07-07 20:19:36 +00:00
if ( section ) /* match on a specific section */
1999-04-16 01:35:26 +00:00
{
fixup_psymbol_section ( p , psymtab - > objfile ) ;
if ( SYMBOL_BFD_SECTION ( p ) ! = section )
continue ;
}
best_pc = SYMBOL_VALUE_ADDRESS ( p ) ;
best = p ;
}
}
for ( pp = psymtab - > objfile - > static_psymbols . list + psymtab - > statics_offset ;
1999-07-07 20:19:36 +00:00
( pp - ( psymtab - > objfile - > static_psymbols . list + psymtab - > statics_offset )
< psymtab - > n_static_syms ) ;
1999-04-16 01:35:26 +00:00
pp + + )
{
p = * pp ;
if ( SYMBOL_NAMESPACE ( p ) = = VAR_NAMESPACE
& & SYMBOL_CLASS ( p ) = = LOC_BLOCK
& & pc > = SYMBOL_VALUE_ADDRESS ( p )
& & ( SYMBOL_VALUE_ADDRESS ( p ) > best_pc
1999-07-07 20:19:36 +00:00
| | ( psymtab - > textlow = = 0
1999-04-16 01:35:26 +00:00
& & best_pc = = 0 & & SYMBOL_VALUE_ADDRESS ( p ) = = 0 ) ) )
{
1999-07-07 20:19:36 +00:00
if ( section ) /* match on a specific section */
1999-04-16 01:35:26 +00:00
{
fixup_psymbol_section ( p , psymtab - > objfile ) ;
if ( SYMBOL_BFD_SECTION ( p ) ! = section )
continue ;
}
best_pc = SYMBOL_VALUE_ADDRESS ( p ) ;
best = p ;
}
}
return best ;
}
/* Find which partial symbol within a psymtab matches PC. Return 0 if none.
Check all psymtabs if PSYMTAB is 0. Backwards compatibility , no section . */
struct partial_symbol *
2000-07-30 01:48:28 +00:00
find_pc_psymbol ( struct partial_symtab * psymtab , CORE_ADDR pc )
1999-04-16 01:35:26 +00:00
{
return find_pc_sect_psymbol ( psymtab , pc , find_pc_mapped_section ( pc ) ) ;
}
/* Debug symbols usually don't have section information. We need to dig that
out of the minimal symbols and stash that in the debug symbol . */
static void
2000-07-30 01:48:28 +00:00
fixup_section ( struct general_symbol_info * ginfo , struct objfile * objfile )
1999-04-16 01:35:26 +00:00
{
struct minimal_symbol * msym ;
msym = lookup_minimal_symbol ( ginfo - > name , NULL , objfile ) ;
if ( msym )
2000-08-04 23:13:50 +00:00
{
ginfo - > bfd_section = SYMBOL_BFD_SECTION ( msym ) ;
ginfo - > section = SYMBOL_SECTION ( msym ) ;
}
1999-04-16 01:35:26 +00:00
}
struct symbol *
2000-07-30 01:48:28 +00:00
fixup_symbol_section ( struct symbol * sym , struct objfile * objfile )
1999-04-16 01:35:26 +00:00
{
if ( ! sym )
return NULL ;
if ( SYMBOL_BFD_SECTION ( sym ) )
return sym ;
fixup_section ( & sym - > ginfo , objfile ) ;
return sym ;
}
2000-08-04 23:13:50 +00:00
struct partial_symbol *
2000-07-30 01:48:28 +00:00
fixup_psymbol_section ( struct partial_symbol * psym , struct objfile * objfile )
1999-04-16 01:35:26 +00:00
{
if ( ! psym )
return NULL ;
if ( SYMBOL_BFD_SECTION ( psym ) )
return psym ;
fixup_section ( & psym - > ginfo , objfile ) ;
return psym ;
}
/* Find the definition for a specified symbol name NAME
in namespace NAMESPACE , visible from lexical block BLOCK .
Returns the struct symbol pointer , or zero if no symbol is found .
If SYMTAB is non - NULL , store the symbol table in which the
symbol was found there , or NULL if not found .
C + + : if IS_A_FIELD_OF_THIS is nonzero on entry , check to see if
NAME is a field of the current implied argument ` this ' . If so set
* IS_A_FIELD_OF_THIS to 1 , otherwise set it to zero .
BLOCK_FOUND is set to the block in which NAME is found ( in the case of
a field of ` this ' , value_of_this sets BLOCK_FOUND to the proper value . ) */
/* This function has a bunch of loops in it and it would seem to be
attractive to put in some QUIT ' s ( though I ' m not really sure
whether it can run long enough to be really important ) . But there
are a few calls for which it would appear to be bad news to quit
out of here : find_proc_desc in alpha - tdep . c and mips - tdep . c , and
nindy_frame_chain_valid in nindy - tdep . c . ( Note that there is C + +
code below which can error ( ) , but that probably doesn ' t affect
these calls since they are looking for a known variable and thus
can probably assume it will never hit the C + + code ) . */
struct symbol *
2000-10-12 16:53:06 +00:00
lookup_symbol ( const char * name , const struct block * block ,
2000-07-30 01:48:28 +00:00
const namespace_enum namespace , int * is_a_field_of_this ,
struct symtab * * symtab )
1999-04-16 01:35:26 +00:00
{
2002-07-30 15:42:07 +00:00
char * demangled_name = NULL ;
const char * modified_name = NULL ;
2002-03-22 18:57:08 +00:00
const char * mangled_name = NULL ;
2000-10-12 16:53:06 +00:00
int needtofreename = 0 ;
struct symbol * returnval ;
1999-04-16 01:35:26 +00:00
2002-07-30 15:42:07 +00:00
modified_name = name ;
/* If we are using C++ language, demangle the name before doing a lookup, so
we can always binary search . */
if ( current_language - > la_language = = language_cplus )
{
demangled_name = cplus_demangle ( name , DMGL_ANSI | DMGL_PARAMS ) ;
if ( demangled_name )
{
mangled_name = name ;
modified_name = demangled_name ;
needtofreename = 1 ;
}
}
2000-08-10 Jimmy Guo <guo@cup.hp.com>
* c-lang.c: Set case sensitivity on for c_language_defn,
cplus_language_defn, and asm_language_defn.
* ch-lang.c: Set case sensitivity on for chill_language_defn.
* f-lang.c: Set case sensivitity off for f_language_defn.
* jv-lang.c: Set case sensitivity on for java_language_defn.
* language.h: Add enum case_mode, case_sensitivity.
* language.c: Define case_mode, case_sensitivity. Set case
sensitivity on for unknown_language_defn, auto_language_defn,
and local_language_defn.
(show_case_command,set_case_command,set_case_str): New static func.
(set_type_range_case): New static func, replaces set_type_range ().
(set_language_command,set_type_command,set_range_command,set_language):
Call set_type_range_case ().
(language_info): Print case sensitivity setting.
(_initialize_language): Add set/show commands for 'case-sensitive'.
Set default case mode 'auto'. Set default language 'auto'.
* m2-lang.c: Set case sensitivity on for m2_language_defn.
* p-lang.c: Set case sensitivity on for pascal_language_defn.
* scm-lang.c: Set case sensitivity off for scm_language_defn.
* symtab.c (lookup_symbol): Downcase symbol name if case sensivitity
is off.
2000-08-11 01:02:35 +00:00
if ( case_sensitivity = = case_sensitive_off )
{
char * copy ;
int len , i ;
len = strlen ( name ) ;
copy = ( char * ) alloca ( len + 1 ) ;
for ( i = 0 ; i < len ; i + + )
copy [ i ] = tolower ( name [ i ] ) ;
copy [ len ] = 0 ;
2000-10-12 16:53:06 +00:00
modified_name = copy ;
2000-08-10 Jimmy Guo <guo@cup.hp.com>
* c-lang.c: Set case sensitivity on for c_language_defn,
cplus_language_defn, and asm_language_defn.
* ch-lang.c: Set case sensitivity on for chill_language_defn.
* f-lang.c: Set case sensivitity off for f_language_defn.
* jv-lang.c: Set case sensitivity on for java_language_defn.
* language.h: Add enum case_mode, case_sensitivity.
* language.c: Define case_mode, case_sensitivity. Set case
sensitivity on for unknown_language_defn, auto_language_defn,
and local_language_defn.
(show_case_command,set_case_command,set_case_str): New static func.
(set_type_range_case): New static func, replaces set_type_range ().
(set_language_command,set_type_command,set_range_command,set_language):
Call set_type_range_case ().
(language_info): Print case sensitivity setting.
(_initialize_language): Add set/show commands for 'case-sensitive'.
Set default case mode 'auto'. Set default language 'auto'.
* m2-lang.c: Set case sensitivity on for m2_language_defn.
* p-lang.c: Set case sensitivity on for pascal_language_defn.
* scm-lang.c: Set case sensitivity off for scm_language_defn.
* symtab.c (lookup_symbol): Downcase symbol name if case sensivitity
is off.
2000-08-11 01:02:35 +00:00
}
2000-10-12 16:53:06 +00:00
2002-03-22 18:57:08 +00:00
returnval = lookup_symbol_aux ( modified_name , mangled_name , block ,
namespace , is_a_field_of_this , symtab ) ;
2000-10-12 16:53:06 +00:00
if ( needtofreename )
2002-07-30 15:42:07 +00:00
xfree ( demangled_name ) ;
2000-10-12 16:53:06 +00:00
return returnval ;
}
static struct symbol *
2002-03-22 18:57:08 +00:00
lookup_symbol_aux ( const char * name , const char * mangled_name ,
const struct block * block , const namespace_enum namespace ,
int * is_a_field_of_this , struct symtab * * symtab )
2000-10-12 16:53:06 +00:00
{
2002-11-05 20:33:01 +00:00
struct symbol * sym ;
2002-12-05 21:26:57 +00:00
const struct block * static_block ;
2002-12-04 22:54:59 +00:00
/* FIXME: carlton/2002-11-05: This variable is here so that
lookup_symbol_aux will sometimes return NULL after receiving a
NULL return value from lookup_symbol_aux_minsyms , without
proceeding on to the partial symtab and static variable tests . I
suspect that that ' s a bad idea . */
int force_return ;
2000-08-10 Jimmy Guo <guo@cup.hp.com>
* c-lang.c: Set case sensitivity on for c_language_defn,
cplus_language_defn, and asm_language_defn.
* ch-lang.c: Set case sensitivity on for chill_language_defn.
* f-lang.c: Set case sensivitity off for f_language_defn.
* jv-lang.c: Set case sensitivity on for java_language_defn.
* language.h: Add enum case_mode, case_sensitivity.
* language.c: Define case_mode, case_sensitivity. Set case
sensitivity on for unknown_language_defn, auto_language_defn,
and local_language_defn.
(show_case_command,set_case_command,set_case_str): New static func.
(set_type_range_case): New static func, replaces set_type_range ().
(set_language_command,set_type_command,set_range_command,set_language):
Call set_type_range_case ().
(language_info): Print case sensitivity setting.
(_initialize_language): Add set/show commands for 'case-sensitive'.
Set default case mode 'auto'. Set default language 'auto'.
* m2-lang.c: Set case sensitivity on for m2_language_defn.
* p-lang.c: Set case sensitivity on for pascal_language_defn.
* scm-lang.c: Set case sensitivity off for scm_language_defn.
* symtab.c (lookup_symbol): Downcase symbol name if case sensivitity
is off.
2000-08-11 01:02:35 +00:00
2002-12-05 21:26:57 +00:00
/* Search specified block and its superiors. Don't search
STATIC_BLOCK or GLOBAL_BLOCK . */
1999-04-16 01:35:26 +00:00
2002-11-05 20:33:01 +00:00
sym = lookup_symbol_aux_local ( name , mangled_name , block , namespace ,
2002-12-05 21:26:57 +00:00
symtab , & static_block ) ;
2002-11-05 20:33:01 +00:00
if ( sym ! = NULL )
return sym ;
1999-04-16 01:35:26 +00:00
2002-11-05 20:33:01 +00:00
#if 0
/* NOTE: carlton/2002-11-05: At the time that this code was
# ifdeffed out, the value of 'block' was always NULL at this
point , hence the bemused comments below . */
1999-04-16 01:35:26 +00:00
/* FIXME: this code is never executed--block is always NULL at this
point . What is it trying to do , anyway ? We already should have
checked the STATIC_BLOCK above ( it is the superblock of top - level
blocks ) . Why is VAR_NAMESPACE special - cased ? */
/* Don't need to mess with the psymtabs; if we have a block,
that file is read in . If we don ' t , then we deal later with
all the psymtab stuff that needs checking . */
/* Note (RT): The following never-executed code looks unnecessary to me also.
* If we change the code to use the original ( passed - in )
* value of ' block ' , we could cause it to execute , but then what
* would it do ? The STATIC_BLOCK of the symtab containing the passed - in
* ' block ' was already searched by the above code . And the STATIC_BLOCK ' s
* of * other * symtabs ( those files not containing ' block ' lexically )
* should not contain ' block ' address - wise . So we wouldn ' t expect this
* code to find any ' sym ' ' s that were not found above . I vote for
* deleting the following paragraph of code .
*/
if ( namespace = = VAR_NAMESPACE & & block ! = NULL )
{
struct block * b ;
/* Find the right symtab. */
ALL_SYMTABS ( objfile , s )
1999-07-07 20:19:36 +00:00
{
bv = BLOCKVECTOR ( s ) ;
b = BLOCKVECTOR_BLOCK ( bv , STATIC_BLOCK ) ;
if ( BLOCK_START ( b ) < = BLOCK_START ( block )
& & BLOCK_END ( b ) > BLOCK_START ( block ) )
{
2002-03-22 18:57:08 +00:00
sym = lookup_block_symbol ( b , name , mangled_name , VAR_NAMESPACE ) ;
1999-07-07 20:19:36 +00:00
if ( sym )
{
block_found = b ;
if ( symtab ! = NULL )
* symtab = s ;
return fixup_symbol_section ( sym , objfile ) ;
}
}
}
1999-04-16 01:35:26 +00:00
}
2002-11-05 20:33:01 +00:00
# endif /* 0 */
1999-04-16 01:35:26 +00:00
/* C++: If requested to do so by the caller,
check to see if NAME is a field of ` this ' . */
if ( is_a_field_of_this )
{
struct value * v = value_of_this ( 0 ) ;
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
* is_a_field_of_this = 0 ;
if ( v & & check_field ( v , name ) )
{
* is_a_field_of_this = 1 ;
if ( symtab ! = NULL )
* symtab = NULL ;
return NULL ;
}
}
2002-12-05 21:26:57 +00:00
/* If there's a static block to search, search it next. */
/* NOTE: carlton/2002-12-05: There is a question as to whether or
not it would be appropriate to search the current global block
here as well . ( That ' s what this code used to do before the
is_a_field_of_this check was moved up . ) On the one hand , it ' s
redundant with the lookup_symbol_aux_symtabs search that happens
next . On the other hand , if decode_line_1 is passed an argument
like filename : var , then the user presumably wants ' var ' to be
searched for in filename . On the third hand , there shouldn ' t be
multiple global variables all of which are named ' var ' , and it ' s
not like decode_line_1 has ever restricted its search to only
global variables in a single filename . All in all , only
searching the static block here seems best : it ' s correct and it ' s
cleanest . */
/* NOTE: carlton/2002-12-05: There's also a possible performance
issue here : if you usually search for global symbols in the
current file , then it would be slightly better to search the
current global block before searching all the symtabs . But there
are other factors that have a much greater effect on performance
than that one , so I don ' t think we should worry about that for
now . */
if ( static_block ! = NULL )
{
sym = lookup_symbol_aux_block ( name , mangled_name , static_block ,
namespace , symtab ) ;
if ( sym ! = NULL )
return sym ;
}
1999-04-16 01:35:26 +00:00
/* Now search all global blocks. Do the symtab's first, then
check the psymtab ' s . If a psymtab indicates the existence
of the desired name as a global , then do psymtab - to - symtab
conversion on the fly and return the found symbol . */
1999-07-07 20:19:36 +00:00
2002-11-05 20:33:01 +00:00
sym = lookup_symbol_aux_symtabs ( GLOBAL_BLOCK , name , mangled_name ,
namespace , symtab ) ;
if ( sym ! = NULL )
return sym ;
1999-04-16 01:35:26 +00:00
# ifndef HPUXHPPA
/* Check for the possibility of the symbol being a function or
a mangled variable that is stored in one of the minimal symbol tables .
Eventually , all global symbols might be resolved in this way . */
1999-07-07 20:19:36 +00:00
2002-12-04 22:54:59 +00:00
force_return = 0 ;
2002-08-30 03:24:00 +00:00
2002-12-04 22:54:59 +00:00
sym = lookup_symbol_aux_minsyms ( name , mangled_name ,
namespace , is_a_field_of_this ,
symtab , & force_return ) ;
if ( sym ! = NULL | | force_return = = 1 )
return sym ;
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
# endif
2002-11-05 20:33:01 +00:00
sym = lookup_symbol_aux_psymtabs ( GLOBAL_BLOCK , name , mangled_name ,
namespace , symtab ) ;
if ( sym ! = NULL )
return sym ;
1999-04-16 01:35:26 +00:00
2002-11-05 20:33:01 +00:00
/* Now search all static file-level symbols. Not strictly correct,
but more useful than an error . Do the symtabs first , then check
the psymtabs . If a psymtab indicates the existence of the
desired name as a file - level static , then do psymtab - to - symtab
1999-04-16 01:35:26 +00:00
conversion on the fly and return the found symbol . */
2002-11-05 20:33:01 +00:00
sym = lookup_symbol_aux_symtabs ( STATIC_BLOCK , name , mangled_name ,
namespace , symtab ) ;
if ( sym ! = NULL )
return sym ;
sym = lookup_symbol_aux_psymtabs ( STATIC_BLOCK , name , mangled_name ,
namespace , symtab ) ;
if ( sym ! = NULL )
return sym ;
1999-04-16 01:35:26 +00:00
# ifdef HPUXHPPA
/* Check for the possibility of the symbol being a function or
a global variable that is stored in one of the minimal symbol tables .
The " minimal symbol table " is built from linker - supplied info .
RT : I moved this check to last , after the complete search of
the global ( p ) symtab ' s and static ( p ) symtab ' s . For HP - generated
symbol tables , this check was causing a premature exit from
lookup_symbol with NULL return , and thus messing up symbol lookups
of things like " c::f " . It seems to me a check of the minimal
symbol table ought to be a last resort in any case . I ' m vaguely
worried about the comment below which talks about FORTRAN routines " foo_ "
though . . . is it saying we need to do the " minsym " check before
the static check in this case ?
*/
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
2002-12-04 22:54:59 +00:00
force_return = 0 ;
1999-04-16 01:35:26 +00:00
2002-12-04 22:54:59 +00:00
sym = lookup_symbol_aux_minsyms ( name , mangled_name ,
namespace , is_a_field_of_this ,
symtab , & force_return ) ;
if ( sym ! = NULL | | force_return = = 1 )
return sym ;
1999-04-16 01:35:26 +00:00
# endif
if ( symtab ! = NULL )
* symtab = NULL ;
2002-11-05 20:33:01 +00:00
return NULL ;
1999-04-16 01:35:26 +00:00
}
2002-11-05 20:33:01 +00:00
2002-12-05 21:26:57 +00:00
/* Check to see if the symbol is defined in BLOCK or its superiors.
Don ' t search STATIC_BLOCK or GLOBAL_BLOCK . If we don ' t find a
match , store the address of STATIC_BLOCK in static_block . */
2002-11-05 20:33:01 +00:00
static struct symbol *
lookup_symbol_aux_local ( const char * name , const char * mangled_name ,
const struct block * block ,
const namespace_enum namespace ,
2002-12-05 21:26:57 +00:00
struct symtab * * symtab ,
const struct block * * static_block )
2002-11-05 20:33:01 +00:00
{
struct symbol * sym ;
2002-12-05 21:07:49 +00:00
2002-12-05 21:26:57 +00:00
/* Check if either no block is specified or it's a global block. */
if ( block = = NULL | | BLOCK_SUPERBLOCK ( block ) = = NULL )
{
* static_block = NULL ;
return NULL ;
}
while ( BLOCK_SUPERBLOCK ( BLOCK_SUPERBLOCK ( block ) ) ! = NULL )
2002-12-05 21:07:49 +00:00
{
sym = lookup_symbol_aux_block ( name , mangled_name , block , namespace ,
symtab ) ;
if ( sym ! = NULL )
return sym ;
block = BLOCK_SUPERBLOCK ( block ) ;
}
2002-12-05 21:26:57 +00:00
/* We've reached the static block. */
* static_block = block ;
2002-12-05 21:07:49 +00:00
return NULL ;
}
/* Look up a symbol in a block; if found, locate its symtab, fixup the
symbol , and set block_found appropriately . */
static struct symbol *
lookup_symbol_aux_block ( const char * name , const char * mangled_name ,
const struct block * block ,
const namespace_enum namespace ,
struct symtab * * symtab )
{
struct symbol * sym ;
2002-11-05 20:33:01 +00:00
struct objfile * objfile = NULL ;
struct blockvector * bv ;
struct block * b ;
struct symtab * s = NULL ;
2002-12-05 21:07:49 +00:00
sym = lookup_block_symbol ( block , name , mangled_name , namespace ) ;
if ( sym )
2002-11-05 20:33:01 +00:00
{
2002-12-05 21:07:49 +00:00
block_found = block ;
if ( symtab ! = NULL )
2002-11-05 20:33:01 +00:00
{
2002-12-05 21:07:49 +00:00
/* Search the list of symtabs for one which contains the
address of the start of this block . */
ALL_SYMTABS ( objfile , s )
2002-11-05 20:33:01 +00:00
{
2002-12-05 21:07:49 +00:00
bv = BLOCKVECTOR ( s ) ;
b = BLOCKVECTOR_BLOCK ( bv , GLOBAL_BLOCK ) ;
if ( BLOCK_START ( b ) < = BLOCK_START ( block )
& & BLOCK_END ( b ) > BLOCK_START ( block ) )
goto found ;
2002-11-05 20:33:01 +00:00
}
2002-12-05 21:07:49 +00:00
found :
* symtab = s ;
2002-11-05 20:33:01 +00:00
}
2002-12-05 21:07:49 +00:00
return fixup_symbol_section ( sym , objfile ) ;
2002-11-05 20:33:01 +00:00
}
return NULL ;
}
/* Check to see if the symbol is defined in one of the symtabs.
BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK ,
depending on whether or not we want to search global symbols or
static symbols . */
static struct symbol *
lookup_symbol_aux_symtabs ( int block_index ,
const char * name , const char * mangled_name ,
const namespace_enum namespace ,
struct symtab * * symtab )
{
struct symbol * sym ;
struct objfile * objfile ;
struct blockvector * bv ;
const struct block * block ;
struct symtab * s ;
ALL_SYMTABS ( objfile , s )
{
bv = BLOCKVECTOR ( s ) ;
block = BLOCKVECTOR_BLOCK ( bv , block_index ) ;
sym = lookup_block_symbol ( block , name , mangled_name , namespace ) ;
if ( sym )
{
block_found = block ;
if ( symtab ! = NULL )
* symtab = s ;
return fixup_symbol_section ( sym , objfile ) ;
}
}
return NULL ;
}
/* Check to see if the symbol is defined in one of the partial
symtabs . BLOCK_INDEX should be either GLOBAL_BLOCK or
STATIC_BLOCK , depending on whether or not we want to search global
symbols or static symbols . */
static struct symbol *
lookup_symbol_aux_psymtabs ( int block_index , const char * name ,
const char * mangled_name ,
const namespace_enum namespace ,
struct symtab * * symtab )
{
struct symbol * sym ;
struct objfile * objfile ;
struct blockvector * bv ;
const struct block * block ;
struct partial_symtab * ps ;
struct symtab * s ;
const int psymtab_index = ( block_index = = GLOBAL_BLOCK ? 1 : 0 ) ;
ALL_PSYMTABS ( objfile , ps )
{
if ( ! ps - > readin
& & lookup_partial_symbol ( ps , name , psymtab_index , namespace ) )
{
s = PSYMTAB_TO_SYMTAB ( ps ) ;
bv = BLOCKVECTOR ( s ) ;
block = BLOCKVECTOR_BLOCK ( bv , block_index ) ;
sym = lookup_block_symbol ( block , name , mangled_name , namespace ) ;
if ( ! sym )
{
/* This shouldn't be necessary, but as a last resort try
looking in the statics even though the psymtab claimed
the symbol was global , or vice - versa . It ' s possible
that the psymtab gets it wrong in some cases . */
/* FIXME: carlton/2002-09-30: Should we really do that?
If that happens , isn ' t it likely to be a GDB error , in
which case we should fix the GDB error rather than
silently dealing with it here ? So I ' d vote for
removing the check for the symbol in the other
block . */
block = BLOCKVECTOR_BLOCK ( bv ,
block_index = = GLOBAL_BLOCK ?
STATIC_BLOCK : GLOBAL_BLOCK ) ;
sym = lookup_block_symbol ( block , name , mangled_name , namespace ) ;
if ( ! sym )
error ( " Internal: %s symbol `%s' found in %s psymtab but not in symtab. \n %s may be an inlined function, or may be a template function \n (if a template, try specifying an instantiation: %s<type>). " ,
block_index = = GLOBAL_BLOCK ? " global " : " static " ,
name , ps - > filename , name , name ) ;
}
if ( symtab ! = NULL )
* symtab = s ;
return fixup_symbol_section ( sym , objfile ) ;
}
}
return NULL ;
}
2002-12-04 22:54:59 +00:00
/* Check for the possibility of the symbol being a function or a
mangled variable that is stored in one of the minimal symbol
tables . Eventually , all global symbols might be resolved in this
way . */
static struct symbol *
lookup_symbol_aux_minsyms ( const char * name ,
const char * mangled_name ,
const namespace_enum namespace ,
int * is_a_field_of_this ,
struct symtab * * symtab ,
int * force_return )
{
struct symbol * sym ;
struct blockvector * bv ;
const struct block * block ;
struct minimal_symbol * msymbol ;
struct symtab * s ;
if ( namespace = = VAR_NAMESPACE )
{
msymbol = lookup_minimal_symbol ( name , NULL , NULL ) ;
if ( msymbol ! = NULL )
{
/* OK, we found a minimal symbol in spite of not finding any
symbol . There are various possible explanations for
this . One possibility is the symbol exists in code not
compiled - g . Another possibility is that the ' psymtab '
isn ' t doing its job . A third possibility , related to # 2 ,
is that we were confused by name - mangling . For instance ,
maybe the psymtab isn ' t doing its job because it only
know about demangled names , but we were given a mangled
name . . . */
/* We first use the address in the msymbol to try to locate
the appropriate symtab . Note that find_pc_sect_symtab ( )
has a side - effect of doing psymtab - to - symtab expansion ,
for the found symtab . */
s = find_pc_sect_symtab ( SYMBOL_VALUE_ADDRESS ( msymbol ) ,
SYMBOL_BFD_SECTION ( msymbol ) ) ;
if ( s ! = NULL )
{
/* This is a function which has a symtab for its address. */
bv = BLOCKVECTOR ( s ) ;
block = BLOCKVECTOR_BLOCK ( bv , GLOBAL_BLOCK ) ;
/* This call used to pass `SYMBOL_NAME (msymbol)' as the
` name ' argument to lookup_block_symbol . But the name
of a minimal symbol is always mangled , so that seems
to be clearly the wrong thing to pass as the
unmangled name . */
sym =
lookup_block_symbol ( block , name , mangled_name , namespace ) ;
/* We kept static functions in minimal symbol table as well as
in static scope . We want to find them in the symbol table . */
if ( ! sym )
{
block = BLOCKVECTOR_BLOCK ( bv , STATIC_BLOCK ) ;
sym = lookup_block_symbol ( block , name ,
mangled_name , namespace ) ;
}
/* NOTE: carlton/2002-12-04: The following comment was
taken from a time when two versions of this function
were part of the body of lookup_symbol_aux : this
comment was taken from the version of the function
that was # ifdef HPUXHPPA , and the comment was right
before the ' return NULL ' part of lookup_symbol_aux .
( Hence the " Fall through and return 0 " comment . )
Elena did some digging into the situation for
Fortran , and she reports :
" I asked around (thanks to Jeff Knaggs), and I think
the story for Fortran goes like this :
" Apparently, in older Fortrans, '_' was not part of
the user namespace . g77 attached a final ' _ ' to
procedure names as the exported symbols for linkage
( foo_ ) , but the symbols went in the debug info just
like ' foo ' . The rationale behind this is not
completely clear , and maybe it was done to other
symbols as well , not just procedures . " */
/* If we get here with sym == 0, the symbol was
found in the minimal symbol table
but not in the symtab .
Fall through and return 0 to use the msymbol
definition of " foo_ " .
( Note that outer code generally follows up a call
to this routine with a call to lookup_minimal_symbol ( ) ,
so a 0 return means we ' ll just flow into that other routine ) .
This happens for Fortran " foo_ " symbols ,
which are " foo " in the symtab .
This can also happen if " asm " is used to make a
regular symbol but not a debugging symbol , e . g .
asm ( " .globl _main " ) ;
asm ( " _main: " ) ;
*/
if ( symtab ! = NULL & & sym ! = NULL )
* symtab = s ;
* force_return = 1 ;
return fixup_symbol_section ( sym , s - > objfile ) ;
}
else if ( MSYMBOL_TYPE ( msymbol ) ! = mst_text
& & MSYMBOL_TYPE ( msymbol ) ! = mst_file_text
& & ! STREQ ( name , SYMBOL_NAME ( msymbol ) ) )
{
/* This is a mangled variable, look it up by its
mangled name . */
* force_return = 1 ;
return lookup_symbol_aux ( SYMBOL_NAME ( msymbol ) , mangled_name ,
NULL , namespace , is_a_field_of_this ,
symtab ) ;
}
}
}
return NULL ;
}
1999-04-16 01:35:26 +00:00
/* Look, in partial_symtab PST, for symbol NAME. Check the global
symbols if GLOBAL , the static symbols if not */
static struct partial_symbol *
2000-07-30 01:48:28 +00:00
lookup_partial_symbol ( struct partial_symtab * pst , const char * name , int global ,
namespace_enum namespace )
1999-04-16 01:35:26 +00:00
{
2000-06-05 20:49:53 +00:00
struct partial_symbol * temp ;
1999-04-16 01:35:26 +00:00
struct partial_symbol * * start , * * psym ;
struct partial_symbol * * top , * * bottom , * * center ;
int length = ( global ? pst - > n_global_syms : pst - > n_static_syms ) ;
int do_linear_search = 1 ;
2000-06-05 20:49:53 +00:00
1999-04-16 01:35:26 +00:00
if ( length = = 0 )
{
return ( NULL ) ;
}
start = ( global ?
pst - > objfile - > global_psymbols . list + pst - > globals_offset :
1999-07-07 20:19:36 +00:00
pst - > objfile - > static_psymbols . list + pst - > statics_offset ) ;
2000-06-05 20:49:53 +00:00
1999-07-07 20:19:36 +00:00
if ( global ) /* This means we can use a binary search. */
1999-04-16 01:35:26 +00:00
{
do_linear_search = 0 ;
/* Binary search. This search is guaranteed to end with center
pointing at the earliest partial symbol with the correct
1999-07-07 20:19:36 +00:00
name . At that point * all * partial symbols with that name
will be checked against the correct namespace . */
1999-04-16 01:35:26 +00:00
bottom = start ;
top = start + length - 1 ;
while ( top > bottom )
{
center = bottom + ( top - bottom ) / 2 ;
if ( ! ( center < top ) )
2001-02-25 04:45:12 +00:00
internal_error ( __FILE__ , __LINE__ , " failed internal consistency check " ) ;
1999-04-16 01:35:26 +00:00
if ( ! do_linear_search
2000-06-05 20:49:53 +00:00
& & ( SYMBOL_LANGUAGE ( * center ) = = language_java ) )
1999-04-16 01:35:26 +00:00
{
do_linear_search = 1 ;
}
2001-01-19 08:01:47 +00:00
if ( strcmp ( SYMBOL_SOURCE_NAME ( * center ) , name ) > = 0 )
1999-04-16 01:35:26 +00:00
{
top = center ;
}
else
{
bottom = center + 1 ;
}
}
if ( ! ( top = = bottom ) )
2001-02-25 04:45:12 +00:00
internal_error ( __FILE__ , __LINE__ , " failed internal consistency check " ) ;
2000-06-05 20:49:53 +00:00
/* djb - 2000-06-03 - Use SYMBOL_MATCHES_NAME, not a strcmp, so
we don ' t have to force a linear search on C + + . Probably holds true
for JAVA as well , no way to check . */
while ( SYMBOL_MATCHES_NAME ( * top , name ) )
1999-04-16 01:35:26 +00:00
{
if ( SYMBOL_NAMESPACE ( * top ) = = namespace )
{
2000-06-05 20:49:53 +00:00
return ( * top ) ;
1999-04-16 01:35:26 +00:00
}
1999-07-07 20:19:36 +00:00
top + + ;
1999-04-16 01:35:26 +00:00
}
}
/* Can't use a binary search or else we found during the binary search that
we should also do a linear search . */
if ( do_linear_search )
2000-06-05 20:49:53 +00:00
{
1999-04-16 01:35:26 +00:00
for ( psym = start ; psym < start + length ; psym + + )
{
if ( namespace = = SYMBOL_NAMESPACE ( * psym ) )
{
if ( SYMBOL_MATCHES_NAME ( * psym , name ) )
{
return ( * psym ) ;
}
}
}
}
return ( NULL ) ;
}
/* Look up a type named NAME in the struct_namespace. The type returned
must not be opaque - - i . e . , must have at least one field defined
This code was modelled on lookup_symbol - - the parts not relevant to looking
up types were just left out . In particular it ' s assumed here that types
are available in struct_namespace and only at file - static or global blocks . */
struct type *
2000-07-30 01:48:28 +00:00
lookup_transparent_type ( const char * name )
1999-04-16 01:35:26 +00:00
{
register struct symbol * sym ;
register struct symtab * s = NULL ;
register struct partial_symtab * ps ;
struct blockvector * bv ;
register struct objfile * objfile ;
register struct block * block ;
/* Now search all the global symbols. Do the symtab's first, then
check the psymtab ' s . If a psymtab indicates the existence
of the desired name as a global , then do psymtab - to - symtab
conversion on the fly and return the found symbol . */
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
ALL_SYMTABS ( objfile , s )
1999-07-07 20:19:36 +00:00
{
bv = BLOCKVECTOR ( s ) ;
block = BLOCKVECTOR_BLOCK ( bv , GLOBAL_BLOCK ) ;
2002-03-22 18:57:08 +00:00
sym = lookup_block_symbol ( block , name , NULL , STRUCT_NAMESPACE ) ;
1999-07-07 20:19:36 +00:00
if ( sym & & ! TYPE_IS_OPAQUE ( SYMBOL_TYPE ( sym ) ) )
{
return SYMBOL_TYPE ( sym ) ;
}
}
1999-04-16 01:35:26 +00:00
ALL_PSYMTABS ( objfile , ps )
1999-07-07 20:19:36 +00:00
{
if ( ! ps - > readin & & lookup_partial_symbol ( ps , name , 1 , STRUCT_NAMESPACE ) )
{
s = PSYMTAB_TO_SYMTAB ( ps ) ;
bv = BLOCKVECTOR ( s ) ;
block = BLOCKVECTOR_BLOCK ( bv , GLOBAL_BLOCK ) ;
2002-03-22 18:57:08 +00:00
sym = lookup_block_symbol ( block , name , NULL , STRUCT_NAMESPACE ) ;
1999-07-07 20:19:36 +00:00
if ( ! sym )
{
/* This shouldn't be necessary, but as a last resort
* try looking in the statics even though the psymtab
* claimed the symbol was global . It ' s possible that
* the psymtab gets it wrong in some cases .
*/
block = BLOCKVECTOR_BLOCK ( bv , STATIC_BLOCK ) ;
2002-03-22 18:57:08 +00:00
sym = lookup_block_symbol ( block , name , NULL , STRUCT_NAMESPACE ) ;
1999-07-07 20:19:36 +00:00
if ( ! sym )
error ( " Internal: global symbol `%s' found in %s psymtab but not in symtab. \n \
1999-04-16 01:35:26 +00:00
% s may be an inlined function , or may be a template function \ n \
( if a template , try specifying an instantiation : % s < type > ) . " ,
1999-07-07 20:19:36 +00:00
name , ps - > filename , name , name ) ;
}
if ( ! TYPE_IS_OPAQUE ( SYMBOL_TYPE ( sym ) ) )
return SYMBOL_TYPE ( sym ) ;
}
}
1999-04-16 01:35:26 +00:00
/* Now search the static file-level symbols.
Not strictly correct , but more useful than an error .
Do the symtab ' s first , then
check the psymtab ' s . If a psymtab indicates the existence
of the desired name as a file - level static , then do psymtab - to - symtab
conversion on the fly and return the found symbol .
*/
ALL_SYMTABS ( objfile , s )
1999-07-07 20:19:36 +00:00
{
bv = BLOCKVECTOR ( s ) ;
block = BLOCKVECTOR_BLOCK ( bv , STATIC_BLOCK ) ;
2002-03-22 18:57:08 +00:00
sym = lookup_block_symbol ( block , name , NULL , STRUCT_NAMESPACE ) ;
1999-07-07 20:19:36 +00:00
if ( sym & & ! TYPE_IS_OPAQUE ( SYMBOL_TYPE ( sym ) ) )
{
return SYMBOL_TYPE ( sym ) ;
}
}
1999-04-16 01:35:26 +00:00
ALL_PSYMTABS ( objfile , ps )
1999-07-07 20:19:36 +00:00
{
if ( ! ps - > readin & & lookup_partial_symbol ( ps , name , 0 , STRUCT_NAMESPACE ) )
{
s = PSYMTAB_TO_SYMTAB ( ps ) ;
bv = BLOCKVECTOR ( s ) ;
block = BLOCKVECTOR_BLOCK ( bv , STATIC_BLOCK ) ;
2002-03-22 18:57:08 +00:00
sym = lookup_block_symbol ( block , name , NULL , STRUCT_NAMESPACE ) ;
1999-07-07 20:19:36 +00:00
if ( ! sym )
{
/* This shouldn't be necessary, but as a last resort
* try looking in the globals even though the psymtab
* claimed the symbol was static . It ' s possible that
* the psymtab gets it wrong in some cases .
*/
block = BLOCKVECTOR_BLOCK ( bv , GLOBAL_BLOCK ) ;
2002-03-22 18:57:08 +00:00
sym = lookup_block_symbol ( block , name , NULL , STRUCT_NAMESPACE ) ;
1999-07-07 20:19:36 +00:00
if ( ! sym )
error ( " Internal: static symbol `%s' found in %s psymtab but not in symtab. \n \
1999-04-16 01:35:26 +00:00
% s may be an inlined function , or may be a template function \ n \
( if a template , try specifying an instantiation : % s < type > ) . " ,
1999-07-07 20:19:36 +00:00
name , ps - > filename , name , name ) ;
}
if ( ! TYPE_IS_OPAQUE ( SYMBOL_TYPE ( sym ) ) )
return SYMBOL_TYPE ( sym ) ;
}
}
1999-04-16 01:35:26 +00:00
return ( struct type * ) 0 ;
}
/* Find the psymtab containing main(). */
/* FIXME: What about languages without main() or specially linked
executables that have no main ( ) ? */
struct partial_symtab *
2000-07-30 01:48:28 +00:00
find_main_psymtab ( void )
1999-04-16 01:35:26 +00:00
{
register struct partial_symtab * pst ;
register struct objfile * objfile ;
ALL_PSYMTABS ( objfile , pst )
1999-07-07 20:19:36 +00:00
{
2001-07-07 17:19:50 +00:00
if ( lookup_partial_symbol ( pst , main_name ( ) , 1 , VAR_NAMESPACE ) )
1999-07-07 20:19:36 +00:00
{
return ( pst ) ;
}
}
1999-04-16 01:35:26 +00:00
return ( NULL ) ;
}
/* Search BLOCK for symbol NAME in NAMESPACE.
Note that if NAME is the demangled form of a C + + symbol , we will fail
to find a match during the binary search of the non - encoded names , but
for now we don ' t worry about the slight inefficiency of looking for
a match we ' ll never find , since it will go pretty quick . Once the
binary search terminates , we drop through and do a straight linear
search on the symbols . Each symbol which is marked as being a C + +
symbol ( language_cplus set ) has both the encoded and non - encoded names
2002-03-22 18:57:08 +00:00
tested for a match .
If MANGLED_NAME is non - NULL , verify that any symbol we find has this
particular mangled name .
*/
1999-04-16 01:35:26 +00:00
struct symbol *
2000-07-30 01:48:28 +00:00
lookup_block_symbol ( register const struct block * block , const char * name ,
2002-03-22 18:57:08 +00:00
const char * mangled_name ,
2000-07-30 01:48:28 +00:00
const namespace_enum namespace )
1999-04-16 01:35:26 +00:00
{
register int bot , top , inc ;
register struct symbol * sym ;
register struct symbol * sym_found = NULL ;
register int do_linear_search = 1 ;
2002-07-11 20:46:19 +00:00
if ( BLOCK_HASHTABLE ( block ) )
{
unsigned int hash_index ;
hash_index = msymbol_hash_iw ( name ) ;
hash_index = hash_index % BLOCK_BUCKETS ( block ) ;
for ( sym = BLOCK_BUCKET ( block , hash_index ) ; sym ; sym = sym - > hash_next )
{
if ( SYMBOL_NAMESPACE ( sym ) = = namespace
& & ( mangled_name
? strcmp ( SYMBOL_NAME ( sym ) , mangled_name ) = = 0
: SYMBOL_MATCHES_NAME ( sym , name ) ) )
return sym ;
}
return NULL ;
}
1999-04-16 01:35:26 +00:00
/* If the blocks's symbols were sorted, start with a binary search. */
if ( BLOCK_SHOULD_SORT ( block ) )
{
/* Reset the linear search flag so if the binary search fails, we
1999-07-07 20:19:36 +00:00
won ' t do the linear search once unless we find some reason to
2000-10-12 16:53:06 +00:00
do so */
1999-04-16 01:35:26 +00:00
do_linear_search = 0 ;
top = BLOCK_NSYMS ( block ) ;
bot = 0 ;
/* Advance BOT to not far before the first symbol whose name is NAME. */
while ( 1 )
{
inc = ( top - bot + 1 ) ;
/* No need to keep binary searching for the last few bits worth. */
if ( inc < 4 )
{
break ;
}
inc = ( inc > > 1 ) + bot ;
sym = BLOCK_SYM ( block , inc ) ;
2000-10-12 16:53:06 +00:00
if ( ! do_linear_search & & ( SYMBOL_LANGUAGE ( sym ) = = language_java ) )
1999-04-16 01:35:26 +00:00
{
do_linear_search = 1 ;
}
2000-10-12 16:53:06 +00:00
if ( SYMBOL_SOURCE_NAME ( sym ) [ 0 ] < name [ 0 ] )
1999-04-16 01:35:26 +00:00
{
bot = inc ;
}
2000-10-12 16:53:06 +00:00
else if ( SYMBOL_SOURCE_NAME ( sym ) [ 0 ] > name [ 0 ] )
1999-04-16 01:35:26 +00:00
{
top = inc ;
}
2001-01-19 08:01:47 +00:00
else if ( strcmp ( SYMBOL_SOURCE_NAME ( sym ) , name ) < 0 )
1999-04-16 01:35:26 +00:00
{
bot = inc ;
}
else
{
top = inc ;
}
}
/* Now scan forward until we run out of symbols, find one whose
1999-07-07 20:19:36 +00:00
name is greater than NAME , or find one we want . If there is
more than one symbol with the right name and namespace , we
return the first one ; I believe it is now impossible for us
to encounter two symbols with the same name and namespace
here , because blocks containing argument symbols are no
2002-03-22 18:57:08 +00:00
longer sorted . The exception is for C + + , where multiple functions
( cloned constructors / destructors , in particular ) can have
the same demangled name . So if we have a particular
mangled name to match , try to do so . */
1999-04-16 01:35:26 +00:00
top = BLOCK_NSYMS ( block ) ;
while ( bot < top )
{
sym = BLOCK_SYM ( block , bot ) ;
2002-03-22 18:57:08 +00:00
if ( SYMBOL_NAMESPACE ( sym ) = = namespace
& & ( mangled_name
? strcmp ( SYMBOL_NAME ( sym ) , mangled_name ) = = 0
: SYMBOL_MATCHES_NAME ( sym , name ) ) )
2001-01-30 02:49:36 +00:00
{
return sym ;
}
2001-10-17 07:12:57 +00:00
if ( SYMBOL_SOURCE_NAME ( sym ) [ 0 ] > name [ 0 ] )
{
break ;
}
1999-04-16 01:35:26 +00:00
bot + + ;
}
}
/* Here if block isn't sorted, or we fail to find a match during the
binary search above . If during the binary search above , we find a
2001-10-16 03:23:35 +00:00
symbol which is a Java symbol , then we have re - enabled the linear
1999-04-16 01:35:26 +00:00
search flag which was reset when starting the binary search .
This loop is equivalent to the loop above , but hacked greatly for speed .
Note that parameter symbols do not always show up last in the
list ; this loop makes sure to take anything else other than
parameter symbols first ; it only uses parameter symbols as a
last resort . Note that this only takes up extra computation
time on a match . */
if ( do_linear_search )
{
top = BLOCK_NSYMS ( block ) ;
bot = 0 ;
while ( bot < top )
{
sym = BLOCK_SYM ( block , bot ) ;
2002-03-22 18:57:08 +00:00
if ( SYMBOL_NAMESPACE ( sym ) = = namespace
& & ( mangled_name
? strcmp ( SYMBOL_NAME ( sym ) , mangled_name ) = = 0
: SYMBOL_MATCHES_NAME ( sym , name ) ) )
1999-04-16 01:35:26 +00:00
{
/* If SYM has aliases, then use any alias that is active
1999-07-07 20:19:36 +00:00
at the current PC . If no alias is active at the current
PC , then use the main symbol .
1999-04-16 01:35:26 +00:00
1999-07-07 20:19:36 +00:00
? ! ? Is checking the current pc correct ? Is this routine
1999-08-02 23:48:37 +00:00
ever called to look up a symbol from another context ?
FIXME : No , it ' s not correct . If someone sets a
conditional breakpoint at an address , then the
breakpoint ' s ` struct expression ' should refer to the
` struct symbol ' appropriate for the breakpoint ' s
address , which may not be the PC .
Even if it were never called from another context ,
it ' s totally bizarre for lookup_symbol ' s behavior to
depend on the value of the inferior ' s current PC . We
should pass in the appropriate PC as well as the
block . The interface to lookup_symbol should change
to require the caller to provide a PC . */
1999-07-07 20:19:36 +00:00
if ( SYMBOL_ALIASES ( sym ) )
sym = find_active_alias ( sym , read_pc ( ) ) ;
1999-04-16 01:35:26 +00:00
sym_found = sym ;
if ( SYMBOL_CLASS ( sym ) ! = LOC_ARG & &
SYMBOL_CLASS ( sym ) ! = LOC_LOCAL_ARG & &
SYMBOL_CLASS ( sym ) ! = LOC_REF_ARG & &
SYMBOL_CLASS ( sym ) ! = LOC_REGPARM & &
SYMBOL_CLASS ( sym ) ! = LOC_REGPARM_ADDR & &
SYMBOL_CLASS ( sym ) ! = LOC_BASEREG_ARG )
{
break ;
}
}
bot + + ;
}
}
return ( sym_found ) ; /* Will be NULL if not found. */
}
/* Given a main symbol SYM and ADDR, search through the alias
list to determine if an alias is active at ADDR and return
the active alias .
If no alias is active , then return SYM . */
static struct symbol *
2000-07-30 01:48:28 +00:00
find_active_alias ( struct symbol * sym , CORE_ADDR addr )
1999-04-16 01:35:26 +00:00
{
struct range_list * r ;
struct alias_list * aliases ;
/* If we have aliases, check them first. */
aliases = SYMBOL_ALIASES ( sym ) ;
while ( aliases )
{
if ( ! SYMBOL_RANGES ( aliases - > sym ) )
1999-07-07 20:19:36 +00:00
return aliases - > sym ;
1999-04-16 01:35:26 +00:00
for ( r = SYMBOL_RANGES ( aliases - > sym ) ; r ; r = r - > next )
{
if ( r - > start < = addr & & r - > end > addr )
return aliases - > sym ;
}
aliases = aliases - > next ;
}
/* Nothing found, return the main symbol. */
return sym ;
}
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
/* Return the symbol for the function which contains a specified
lexical block , described by a struct block BL . */
struct symbol *
2000-07-30 01:48:28 +00:00
block_function ( struct block * bl )
1999-04-16 01:35:26 +00:00
{
while ( BLOCK_FUNCTION ( bl ) = = 0 & & BLOCK_SUPERBLOCK ( bl ) ! = 0 )
bl = BLOCK_SUPERBLOCK ( bl ) ;
return BLOCK_FUNCTION ( bl ) ;
}
/* Find the symtab associated with PC and SECTION. Look through the
psymtabs and read in another symtab if necessary . */
struct symtab *
2000-07-30 01:48:28 +00:00
find_pc_sect_symtab ( CORE_ADDR pc , asection * section )
1999-04-16 01:35:26 +00:00
{
register struct block * b ;
struct blockvector * bv ;
register struct symtab * s = NULL ;
register struct symtab * best_s = NULL ;
register struct partial_symtab * ps ;
register struct objfile * objfile ;
CORE_ADDR distance = 0 ;
2002-01-31 05:03:31 +00:00
struct minimal_symbol * msymbol ;
/* If we know that this is not a text address, return failure. This is
necessary because we loop based on the block ' s high and low code
addresses , which do not include the data ranges , and because
we call find_pc_sect_psymtab which has a similar restriction based
on the partial_symtab ' s texthigh and textlow . */
msymbol = lookup_minimal_symbol_by_pc_section ( pc , section ) ;
if ( msymbol
& & ( msymbol - > type = = mst_data
| | msymbol - > type = = mst_bss
| | msymbol - > type = = mst_abs
| | msymbol - > type = = mst_file_data
| | msymbol - > type = = mst_file_bss ) )
return NULL ;
1999-04-16 01:35:26 +00:00
/* Search all symtabs for the one whose file contains our address, and which
is the smallest of all the ones containing the address . This is designed
to deal with a case like symtab a is at 0x1000 - 0x2000 and 0x3000 - 0x4000
and symtab b is at 0x2000 - 0x3000 . So the GLOBAL_BLOCK for a is from
0x1000 - 0x4000 , but for address 0x2345 we want to return symtab b .
This happens for native ecoff format , where code from included files
gets its own symtab . The symtab for the included file should have
been read in already via the dependency mechanism .
It might be swifter to create several symtabs with the same name
like xcoff does ( I ' m not sure ) .
It also happens for objfiles that have their functions reordered .
For these , the symtab we are looking for is not necessarily read in . */
ALL_SYMTABS ( objfile , s )
1999-07-07 20:19:36 +00:00
{
bv = BLOCKVECTOR ( s ) ;
b = BLOCKVECTOR_BLOCK ( bv , GLOBAL_BLOCK ) ;
1999-04-16 01:35:26 +00:00
1999-07-07 20:19:36 +00:00
if ( BLOCK_START ( b ) < = pc
& & BLOCK_END ( b ) > pc
& & ( distance = = 0
| | BLOCK_END ( b ) - BLOCK_START ( b ) < distance ) )
{
/* For an objfile that has its functions reordered,
find_pc_psymtab will find the proper partial symbol table
and we simply return its corresponding symtab . */
/* In order to better support objfiles that contain both
stabs and coff debugging info , we continue on if a psymtab
can ' t be found . */
if ( ( objfile - > flags & OBJF_REORDERED ) & & objfile - > psymtabs )
{
ps = find_pc_sect_psymtab ( pc , section ) ;
if ( ps )
return PSYMTAB_TO_SYMTAB ( ps ) ;
}
if ( section ! = 0 )
{
int i ;
2002-07-11 20:46:19 +00:00
struct symbol * sym = NULL ;
1999-04-16 01:35:26 +00:00
2002-07-11 20:46:19 +00:00
ALL_BLOCK_SYMBOLS ( b , i , sym )
1999-07-07 20:19:36 +00:00
{
2002-07-11 20:46:19 +00:00
fixup_symbol_section ( sym , objfile ) ;
if ( section = = SYMBOL_BFD_SECTION ( sym ) )
1999-07-07 20:19:36 +00:00
break ;
}
2002-07-11 20:46:19 +00:00
if ( ( i > = BLOCK_BUCKETS ( b ) ) & & ( sym = = NULL ) )
1999-07-07 20:19:36 +00:00
continue ; /* no symbol in this symtab matches section */
}
distance = BLOCK_END ( b ) - BLOCK_START ( b ) ;
best_s = s ;
}
}
1999-04-16 01:35:26 +00:00
if ( best_s ! = NULL )
1999-07-07 20:19:36 +00:00
return ( best_s ) ;
1999-04-16 01:35:26 +00:00
s = NULL ;
ps = find_pc_sect_psymtab ( pc , section ) ;
if ( ps )
{
if ( ps - > readin )
/* Might want to error() here (in case symtab is corrupt and
will cause a core dump ) , but maybe we can successfully
continue , so let ' s not . */
warning ( " \
2000-07-11 07:56:23 +00:00
( Internal error : pc 0 x % s in read in psymtab , but not in symtab . ) \ n " ,
paddr_nz ( pc ) ) ;
1999-04-16 01:35:26 +00:00
s = PSYMTAB_TO_SYMTAB ( ps ) ;
}
return ( s ) ;
}
/* Find the symtab associated with PC. Look through the psymtabs and
read in another symtab if necessary . Backward compatibility , no section */
struct symtab *
2000-07-30 01:48:28 +00:00
find_pc_symtab ( CORE_ADDR pc )
1999-04-16 01:35:26 +00:00
{
return find_pc_sect_symtab ( pc , find_pc_mapped_section ( pc ) ) ;
}
1999-07-07 20:19:36 +00:00
2000-10-27 15:02:42 +00:00
/* Find the source file and line number for a given PC value and SECTION.
1999-04-16 01:35:26 +00:00
Return a structure containing a symtab pointer , a line number ,
and a pc range for the entire source line .
The value ' s . pc field is NOT the specified pc .
NOTCURRENT nonzero means , if specified pc is on a line boundary ,
use the line that ends there . Otherwise , in that case , the line
that begins there is used . */
/* The big complication here is that a line may start in one file, and end just
before the start of another file . This usually occurs when you # include
code in the middle of a subroutine . To properly find the end of a line ' s PC
range , we must search all symtabs associated with this compilation unit , and
find the one whose first PC is closer than that of the next line in this
symtab . */
/* If it's worth the effort, we could be using a binary search. */
struct symtab_and_line
2000-07-30 01:48:28 +00:00
find_pc_sect_line ( CORE_ADDR pc , struct sec * section , int notcurrent )
1999-04-16 01:35:26 +00:00
{
struct symtab * s ;
register struct linetable * l ;
register int len ;
register int i ;
register struct linetable_entry * item ;
struct symtab_and_line val ;
struct blockvector * bv ;
struct minimal_symbol * msymbol ;
struct minimal_symbol * mfunsym ;
/* Info on best line seen so far, and where it starts, and its file. */
struct linetable_entry * best = NULL ;
CORE_ADDR best_end = 0 ;
struct symtab * best_symtab = 0 ;
/* Store here the first line number
of a file which contains the line at the smallest pc after PC .
If we don ' t find a line whose range contains PC ,
we will use a line one less than this ,
with a range from the start of that file to the first line ' s pc . */
struct linetable_entry * alt = NULL ;
struct symtab * alt_symtab = 0 ;
/* Info on best line seen in this file. */
struct linetable_entry * prev ;
/* If this pc is not from the current frame,
it is the address of the end of a call instruction .
Quite likely that is the start of the following statement .
But what we want is the statement containing the instruction .
Fudge the pc to make sure we get that . */
2002-10-24 21:02:53 +00:00
init_sal ( & val ) ; /* initialize to zeroes */
1999-04-16 01:35:26 +00:00
2001-11-27 00:03:22 +00:00
/* It's tempting to assume that, if we can't find debugging info for
any function enclosing PC , that we shouldn ' t search for line
number info , either . However , GAS can emit line number info for
assembly files - - - very helpful when debugging hand - written
assembly code . In such a case , we ' d have no debug info for the
function , but we would have line info . */
2001-11-13 16:42:50 +00:00
1999-04-16 01:35:26 +00:00
if ( notcurrent )
pc - = 1 ;
1999-07-07 20:19:36 +00:00
/* elz: added this because this function returned the wrong
1999-04-16 01:35:26 +00:00
information if the pc belongs to a stub ( import / export )
to call a shlib function . This stub would be anywhere between
two functions in the target , and the line info was erroneously
taken to be the one of the line before the pc .
1999-07-07 20:19:36 +00:00
*/
1999-04-16 01:35:26 +00:00
/* RT: Further explanation:
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
* We have stubs ( trampolines ) inserted between procedures .
*
* Example : " shr1 " exists in a shared library , and a " shr1 " stub also
* exists in the main image .
*
* In the minimal symbol table , we have a bunch of symbols
* sorted by start address . The stubs are marked as " trampoline " ,
* the others appear as text . E . g . :
*
* Minimal symbol table for main image
* main : code for main ( text symbol )
* shr1 : stub ( trampoline symbol )
* foo : code for foo ( text symbol )
* . . .
* Minimal symbol table for " shr1 " image :
* . . .
* shr1 : code for shr1 ( text symbol )
* . . .
*
* So the code below is trying to detect if we are in the stub
* ( " shr1 " stub ) , and if so , find the real code ( " shr1 " trampoline ) ,
* and if found , do the symbolization from the real - code address
* rather than the stub address .
*
* Assumptions being made about the minimal symbol table :
* 1. lookup_minimal_symbol_by_pc ( ) will return a trampoline only
* if we ' re really in the trampoline . If we ' re beyond it ( say
* we ' re in " foo " in the above example ) , it ' ll have a closer
* symbol ( the " foo " text symbol for example ) and will not
* return the trampoline .
* 2. lookup_minimal_symbol_text ( ) will find a real text symbol
* corresponding to the trampoline , and whose address will
* be different than the trampoline address . I put in a sanity
* check for the address being the same , to avoid an
* infinite recursion .
*/
1999-07-07 20:19:36 +00:00
msymbol = lookup_minimal_symbol_by_pc ( pc ) ;
if ( msymbol ! = NULL )
1999-04-16 01:35:26 +00:00
if ( MSYMBOL_TYPE ( msymbol ) = = mst_solib_trampoline )
1999-07-07 20:19:36 +00:00
{
mfunsym = lookup_minimal_symbol_text ( SYMBOL_NAME ( msymbol ) , NULL , NULL ) ;
if ( mfunsym = = NULL )
/* I eliminated this warning since it is coming out
* in the following situation :
* gdb shmain // test program with shared libraries
* ( gdb ) break shr1 // function in shared lib
* Warning : In stub for . . .
* In the above situation , the shared lib is not loaded yet ,
* so of course we can ' t find the real func / line info ,
* but the " break " still works , and the warning is annoying .
* So I commented out the warning . RT */
/* warning ("In stub for %s; unable to find real function/line info", SYMBOL_NAME(msymbol)) */ ;
/* fall through */
else if ( SYMBOL_VALUE ( mfunsym ) = = SYMBOL_VALUE ( msymbol ) )
/* Avoid infinite recursion */
/* See above comment about why warning is commented out */
/* warning ("In stub for %s; unable to find real function/line info", SYMBOL_NAME(msymbol)) */ ;
/* fall through */
else
return find_pc_line ( SYMBOL_VALUE ( mfunsym ) , 0 ) ;
}
1999-04-16 01:35:26 +00:00
s = find_pc_sect_symtab ( pc , section ) ;
if ( ! s )
{
/* if no symbol information, return previous pc */
if ( notcurrent )
pc + + ;
val . pc = pc ;
return val ;
}
bv = BLOCKVECTOR ( s ) ;
/* Look at all the symtabs that share this blockvector.
They all have the same apriori range , that we found was right ;
but they have different line tables . */
for ( ; s & & BLOCKVECTOR ( s ) = = bv ; s = s - > next )
{
/* Find the best line in this symtab. */
l = LINETABLE ( s ) ;
if ( ! l )
1999-07-07 20:19:36 +00:00
continue ;
1999-04-16 01:35:26 +00:00
len = l - > nitems ;
if ( len < = 0 )
{
/* I think len can be zero if the symtab lacks line numbers
( e . g . gcc - g1 ) . ( Either that or the LINETABLE is NULL ;
I ' m not sure which , and maybe it depends on the symbol
reader ) . */
continue ;
}
prev = NULL ;
item = l - > item ; /* Get first line info */
/* Is this file's first line closer than the first lines of other files?
1999-07-07 20:19:36 +00:00
If so , record this file , and its first line , as best alternate . */
1999-04-16 01:35:26 +00:00
if ( item - > pc > pc & & ( ! alt | | item - > pc < alt - > pc ) )
{
alt = item ;
alt_symtab = s ;
}
for ( i = 0 ; i < len ; i + + , item + + )
{
/* Leave prev pointing to the linetable entry for the last line
that started at or before PC . */
if ( item - > pc > pc )
break ;
prev = item ;
}
/* At this point, prev points at the line whose start addr is <= pc, and
1999-07-07 20:19:36 +00:00
item points at the next line . If we ran off the end of the linetable
( pc > = start of the last line ) , then prev = = item . If pc < start of
the first line , prev will not be set . */
1999-04-16 01:35:26 +00:00
/* Is this file's best line closer than the best in the other files?
1999-07-07 20:19:36 +00:00
If so , record this file , and its best line , as best so far . */
1999-04-16 01:35:26 +00:00
if ( prev & & ( ! best | | prev - > pc > best - > pc ) )
{
best = prev ;
best_symtab = s ;
2001-03-27 01:17:47 +00:00
/* Discard BEST_END if it's before the PC of the current BEST. */
if ( best_end < = best - > pc )
best_end = 0 ;
1999-04-16 01:35:26 +00:00
}
2001-03-27 01:17:47 +00:00
/* If another line (denoted by ITEM) is in the linetable and its
PC is after BEST ' s PC , but before the current BEST_END , then
use ITEM ' s PC as the new best_end . */
if ( best & & i < len & & item - > pc > best - > pc
& & ( best_end = = 0 | | best_end > item - > pc ) )
best_end = item - > pc ;
1999-04-16 01:35:26 +00:00
}
if ( ! best_symtab )
{
if ( ! alt_symtab )
{ /* If we didn't find any line # info, just
return zeros . */
val . pc = pc ;
}
else
{
val . symtab = alt_symtab ;
val . line = alt - > line - 1 ;
/* Don't return line 0, that means that we didn't find the line. */
1999-07-07 20:19:36 +00:00
if ( val . line = = 0 )
+ + val . line ;
1999-04-16 01:35:26 +00:00
val . pc = BLOCK_END ( BLOCKVECTOR_BLOCK ( bv , GLOBAL_BLOCK ) ) ;
val . end = alt - > pc ;
}
}
2002-02-22 00:17:13 +00:00
else if ( best - > line = = 0 )
{
/* If our best fit is in a range of PC's for which no line
number info is available ( line number is zero ) then we didn ' t
find any valid line information . */
val . pc = pc ;
}
1999-04-16 01:35:26 +00:00
else
{
val . symtab = best_symtab ;
val . line = best - > line ;
val . pc = best - > pc ;
if ( best_end & & ( ! alt | | best_end < alt - > pc ) )
val . end = best_end ;
else if ( alt )
val . end = alt - > pc ;
else
val . end = BLOCK_END ( BLOCKVECTOR_BLOCK ( bv , GLOBAL_BLOCK ) ) ;
}
val . section = section ;
return val ;
}
/* Backward compatibility (no section) */
struct symtab_and_line
2000-07-30 01:48:28 +00:00
find_pc_line ( CORE_ADDR pc , int notcurrent )
1999-04-16 01:35:26 +00:00
{
1999-07-07 20:19:36 +00:00
asection * section ;
1999-04-16 01:35:26 +00:00
section = find_pc_overlay ( pc ) ;
if ( pc_in_unmapped_range ( pc , section ) )
pc = overlay_mapped_address ( pc , section ) ;
return find_pc_sect_line ( pc , section , notcurrent ) ;
}
/* Find line number LINE in any symtab whose name is the same as
SYMTAB .
If found , return the symtab that contains the linetable in which it was
found , set * INDEX to the index in the linetable of the best entry
found , and set * EXACT_MATCH nonzero if the value returned is an
exact match .
If not found , return NULL . */
2000-11-10 23:02:56 +00:00
struct symtab *
2000-07-30 01:48:28 +00:00
find_line_symtab ( struct symtab * symtab , int line , int * index , int * exact_match )
1999-04-16 01:35:26 +00:00
{
int exact ;
/* BEST_INDEX and BEST_LINETABLE identify the smallest linenumber > LINE
so far seen . */
int best_index ;
struct linetable * best_linetable ;
struct symtab * best_symtab ;
/* First try looking it up in the given symtab. */
best_linetable = LINETABLE ( symtab ) ;
best_symtab = symtab ;
best_index = find_line_common ( best_linetable , line , & exact ) ;
if ( best_index < 0 | | ! exact )
{
/* Didn't find an exact match. So we better keep looking for
1999-07-07 20:19:36 +00:00
another symtab with the same name . In the case of xcoff ,
multiple csects for one source file ( produced by IBM ' s FORTRAN
compiler ) produce multiple symtabs ( this is unavoidable
assuming csects can be at arbitrary places in memory and that
the GLOBAL_BLOCK of a symtab has a begin and end address ) . */
1999-04-16 01:35:26 +00:00
/* BEST is the smallest linenumber > LINE so far seen,
1999-07-07 20:19:36 +00:00
or 0 if none has been seen so far .
BEST_INDEX and BEST_LINETABLE identify the item for it . */
1999-04-16 01:35:26 +00:00
int best ;
struct objfile * objfile ;
struct symtab * s ;
if ( best_index > = 0 )
best = best_linetable - > item [ best_index ] . line ;
else
best = 0 ;
ALL_SYMTABS ( objfile , s )
1999-07-07 20:19:36 +00:00
{
struct linetable * l ;
int ind ;
1999-04-16 01:35:26 +00:00
1999-07-07 20:19:36 +00:00
if ( ! STREQ ( symtab - > filename , s - > filename ) )
continue ;
l = LINETABLE ( s ) ;
ind = find_line_common ( l , line , & exact ) ;
if ( ind > = 0 )
{
if ( exact )
{
best_index = ind ;
best_linetable = l ;
best_symtab = s ;
goto done ;
}
if ( best = = 0 | | l - > item [ ind ] . line < best )
{
best = l - > item [ ind ] . line ;
best_index = ind ;
best_linetable = l ;
best_symtab = s ;
}
}
}
1999-04-16 01:35:26 +00:00
}
1999-07-07 20:19:36 +00:00
done :
1999-04-16 01:35:26 +00:00
if ( best_index < 0 )
return NULL ;
if ( index )
* index = best_index ;
if ( exact_match )
* exact_match = exact ;
return best_symtab ;
}
/* Set the PC value for a given source file and line number and return true.
Returns zero for invalid line number ( and sets the PC to 0 ) .
The source file is specified with a struct symtab . */
int
2000-07-30 01:48:28 +00:00
find_line_pc ( struct symtab * symtab , int line , CORE_ADDR * pc )
1999-04-16 01:35:26 +00:00
{
struct linetable * l ;
int ind ;
* pc = 0 ;
if ( symtab = = 0 )
return 0 ;
symtab = find_line_symtab ( symtab , line , & ind , NULL ) ;
if ( symtab ! = NULL )
{
l = LINETABLE ( symtab ) ;
* pc = l - > item [ ind ] . pc ;
return 1 ;
}
else
return 0 ;
}
/* Find the range of pc values in a line.
Store the starting pc of the line into * STARTPTR
and the ending pc ( start of next line ) into * ENDPTR .
Returns 1 to indicate success .
Returns 0 if could not find the specified line . */
int
2000-07-30 01:48:28 +00:00
find_line_pc_range ( struct symtab_and_line sal , CORE_ADDR * startptr ,
CORE_ADDR * endptr )
1999-04-16 01:35:26 +00:00
{
CORE_ADDR startaddr ;
struct symtab_and_line found_sal ;
startaddr = sal . pc ;
1999-07-07 20:19:36 +00:00
if ( startaddr = = 0 & & ! find_line_pc ( sal . symtab , sal . line , & startaddr ) )
1999-04-16 01:35:26 +00:00
return 0 ;
/* This whole function is based on address. For example, if line 10 has
two parts , one from 0x100 to 0x200 and one from 0x300 to 0x400 , then
" info line *0x123 " should say the line goes from 0x100 to 0x200
and " info line *0x355 " should say the line goes from 0x300 to 0x400 .
This also insures that we never give a range like " starts at 0x134
and ends at 0x12c " . */
found_sal = find_pc_sect_line ( startaddr , sal . section , 0 ) ;
if ( found_sal . line ! = sal . line )
{
/* The specified line (sal) has zero bytes. */
* startptr = found_sal . pc ;
* endptr = found_sal . pc ;
}
else
{
* startptr = found_sal . pc ;
* endptr = found_sal . end ;
}
return 1 ;
}
/* Given a line table and a line number, return the index into the line
table for the pc of the nearest line whose number is > = the specified one .
Return - 1 if none is found . The value is > = 0 if it is an index .
Set * EXACT_MATCH nonzero if the value returned is an exact match . */
static int
2000-07-30 01:48:28 +00:00
find_line_common ( register struct linetable * l , register int lineno ,
int * exact_match )
1999-04-16 01:35:26 +00:00
{
register int i ;
register int len ;
/* BEST is the smallest linenumber > LINENO so far seen,
or 0 if none has been seen so far .
BEST_INDEX identifies the item for it . */
int best_index = - 1 ;
int best = 0 ;
if ( lineno < = 0 )
return - 1 ;
if ( l = = 0 )
return - 1 ;
len = l - > nitems ;
for ( i = 0 ; i < len ; i + + )
{
register struct linetable_entry * item = & ( l - > item [ i ] ) ;
if ( item - > line = = lineno )
{
/* Return the first (lowest address) entry which matches. */
* exact_match = 1 ;
return i ;
}
if ( item - > line > lineno & & ( best = = 0 | | item - > line < best ) )
{
best = item - > line ;
best_index = i ;
}
}
/* If we got here, we didn't get an exact match. */
* exact_match = 0 ;
return best_index ;
}
int
2000-07-30 01:48:28 +00:00
find_pc_line_pc_range ( CORE_ADDR pc , CORE_ADDR * startptr , CORE_ADDR * endptr )
1999-04-16 01:35:26 +00:00
{
struct symtab_and_line sal ;
sal = find_pc_line ( pc , 0 ) ;
* startptr = sal . pc ;
* endptr = sal . end ;
return sal . symtab ! = 0 ;
}
/* Given a function symbol SYM, find the symtab and line for the start
of the function .
If the argument FUNFIRSTLINE is nonzero , we want the first line
of real code inside the function . */
2000-11-10 23:02:56 +00:00
struct symtab_and_line
2000-07-30 01:48:28 +00:00
find_function_start_sal ( struct symbol * sym , int funfirstline )
1999-04-16 01:35:26 +00:00
{
CORE_ADDR pc ;
struct symtab_and_line sal ;
pc = BLOCK_START ( SYMBOL_BLOCK_VALUE ( sym ) ) ;
fixup_symbol_section ( sym , NULL ) ;
if ( funfirstline )
1999-07-07 20:19:36 +00:00
{ /* skip "first line" of function (which is actually its prologue) */
1999-04-16 01:35:26 +00:00
asection * section = SYMBOL_BFD_SECTION ( sym ) ;
/* If function is in an unmapped overlay, use its unmapped LMA
1999-07-07 20:19:36 +00:00
address , so that SKIP_PROLOGUE has something unique to work on */
1999-04-16 01:35:26 +00:00
if ( section_is_overlay ( section ) & &
! section_is_mapped ( section ) )
pc = overlay_unmapped_address ( pc , section ) ;
pc + = FUNCTION_START_OFFSET ;
1999-05-05 14:45:51 +00:00
pc = SKIP_PROLOGUE ( pc ) ;
1999-04-16 01:35:26 +00:00
/* For overlays, map pc back into its mapped VMA range */
pc = overlay_mapped_address ( pc , section ) ;
}
sal = find_pc_sect_line ( pc , SYMBOL_BFD_SECTION ( sym ) , 0 ) ;
# ifdef PROLOGUE_FIRSTLINE_OVERLAP
/* Convex: no need to suppress code on first line, if any */
sal . pc = pc ;
# else
/* Check if SKIP_PROLOGUE left us in mid-line, and the next
line is still part of the same function . */
if ( sal . pc ! = pc
& & BLOCK_START ( SYMBOL_BLOCK_VALUE ( sym ) ) < = sal . end
& & sal . end < BLOCK_END ( SYMBOL_BLOCK_VALUE ( sym ) ) )
{
/* First pc of next line */
pc = sal . end ;
/* Recalculate the line number (might not be N+1). */
sal = find_pc_sect_line ( pc , SYMBOL_BFD_SECTION ( sym ) , 0 ) ;
}
sal . pc = pc ;
# endif
return sal ;
}
2000-11-10 23:02:56 +00:00
1999-04-16 01:35:26 +00:00
/* If P is of the form "operator[ \t]+..." where `...' is
some legitimate operator text , return a pointer to the
beginning of the substring of the operator text .
Otherwise , return " " . */
char *
2000-07-30 01:48:28 +00:00
operator_chars ( char * p , char * * end )
1999-04-16 01:35:26 +00:00
{
* end = " " ;
if ( strncmp ( p , " operator " , 8 ) )
return * end ;
p + = 8 ;
/* Don't get faked out by `operator' being part of a longer
identifier . */
1999-07-07 20:19:36 +00:00
if ( isalpha ( * p ) | | * p = = ' _ ' | | * p = = ' $ ' | | * p = = ' \0 ' )
1999-04-16 01:35:26 +00:00
return * end ;
/* Allow some whitespace between `operator' and the operator symbol. */
while ( * p = = ' ' | | * p = = ' \t ' )
p + + ;
/* Recognize 'operator TYPENAME'. */
1999-07-07 20:19:36 +00:00
if ( isalpha ( * p ) | | * p = = ' _ ' | | * p = = ' $ ' )
1999-04-16 01:35:26 +00:00
{
1999-07-07 20:19:36 +00:00
register char * q = p + 1 ;
while ( isalnum ( * q ) | | * q = = ' _ ' | | * q = = ' $ ' )
1999-04-16 01:35:26 +00:00
q + + ;
* end = q ;
return p ;
}
2001-11-05 23:27:31 +00:00
while ( * p )
switch ( * p )
{
case ' \\ ' : /* regexp quoting */
if ( p [ 1 ] = = ' * ' )
{
if ( p [ 2 ] = = ' = ' ) /* 'operator\*=' */
* end = p + 3 ;
else /* 'operator\*' */
* end = p + 2 ;
return p ;
}
else if ( p [ 1 ] = = ' [ ' )
{
if ( p [ 2 ] = = ' ] ' )
error ( " mismatched quoting on brackets, try 'operator \\ [ \\ ]' " ) ;
else if ( p [ 2 ] = = ' \\ ' & & p [ 3 ] = = ' ] ' )
{
* end = p + 4 ; /* 'operator\[\]' */
return p ;
}
else
error ( " nothing is allowed between '[' and ']' " ) ;
}
else
{
/* Gratuitous qoute: skip it and move on. */
p + + ;
continue ;
}
break ;
case ' ! ' :
case ' = ' :
case ' * ' :
case ' / ' :
case ' % ' :
case ' ^ ' :
if ( p [ 1 ] = = ' = ' )
* end = p + 2 ;
else
* end = p + 1 ;
return p ;
case ' < ' :
case ' > ' :
case ' + ' :
case ' - ' :
case ' & ' :
case ' | ' :
if ( p [ 0 ] = = ' - ' & & p [ 1 ] = = ' > ' )
{
/* Struct pointer member operator 'operator->'. */
if ( p [ 2 ] = = ' * ' )
{
* end = p + 3 ; /* 'operator->*' */
return p ;
}
else if ( p [ 2 ] = = ' \\ ' )
{
* end = p + 4 ; /* Hopefully 'operator->\*' */
return p ;
}
else
{
* end = p + 2 ; /* 'operator->' */
return p ;
}
}
if ( p [ 1 ] = = ' = ' | | p [ 1 ] = = p [ 0 ] )
* end = p + 2 ;
else
* end = p + 1 ;
return p ;
case ' ~ ' :
case ' , ' :
1999-07-07 20:19:36 +00:00
* end = p + 1 ;
2001-11-05 23:27:31 +00:00
return p ;
case ' ( ' :
if ( p [ 1 ] ! = ' ) ' )
error ( " `operator ()' must be specified without whitespace in `()' " ) ;
1999-07-07 20:19:36 +00:00
* end = p + 2 ;
2001-11-05 23:27:31 +00:00
return p ;
case ' ? ' :
if ( p [ 1 ] ! = ' : ' )
error ( " `operator ?:' must be specified without whitespace in `?:' " ) ;
* end = p + 2 ;
return p ;
case ' [ ' :
if ( p [ 1 ] ! = ' ] ' )
error ( " `operator []' must be specified without whitespace in `[]' " ) ;
* end = p + 2 ;
return p ;
default :
error ( " `operator %s' not supported " , p ) ;
break ;
}
1999-04-16 01:35:26 +00:00
* end = " " ;
return * end ;
}
1999-07-07 20:19:36 +00:00
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
/* If FILE is not already in the table of files, return zero;
otherwise return non - zero . Optionally add FILE to the table if ADD
is non - zero . If * FIRST is non - zero , forget the old table
contents . */
static int
filename_seen ( const char * file , int add , int * first )
1999-04-16 01:35:26 +00:00
{
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
/* Table of files seen so far. */
static const char * * tab = NULL ;
1999-04-16 01:35:26 +00:00
/* Allocated size of tab in elements.
Start with one 256 - byte block ( when using GNU malloc . c ) .
24 is the malloc overhead when range checking is in effect . */
static int tab_alloc_size = ( 256 - 24 ) / sizeof ( char * ) ;
/* Current size of tab in elements. */
static int tab_cur_size ;
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
const char * * p ;
1999-04-16 01:35:26 +00:00
if ( * first )
{
if ( tab = = NULL )
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
tab = ( const char * * ) xmalloc ( tab_alloc_size * sizeof ( * tab ) ) ;
1999-04-16 01:35:26 +00:00
tab_cur_size = 0 ;
}
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
/* Is FILE in tab? */
1999-04-16 01:35:26 +00:00
for ( p = tab ; p < tab + tab_cur_size ; p + + )
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
if ( strcmp ( * p , file ) = = 0 )
return 1 ;
/* No; maybe add it to tab. */
if ( add )
1999-04-16 01:35:26 +00:00
{
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
if ( tab_cur_size = = tab_alloc_size )
{
tab_alloc_size * = 2 ;
tab = ( const char * * ) xrealloc ( ( char * ) tab ,
tab_alloc_size * sizeof ( * tab ) ) ;
}
tab [ tab_cur_size + + ] = file ;
1999-04-16 01:35:26 +00:00
}
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
return 0 ;
}
/* Slave routine for sources_info. Force line breaks at ,'s.
NAME is the name to print and * FIRST is nonzero if this is the first
name printed . Set * FIRST to zero . */
static void
output_source_filename ( char * name , int * first )
{
/* Since a single source file can result in several partial symbol
tables , we need to avoid printing it more than once . Note : if
some of the psymtabs are read in and some are not , it gets
printed both under " Source files for which symbols have been
read " and " Source files for which symbols will be read in on
demand " . I consider this a reasonable way to deal with the
situation . I ' m not sure whether this can also happen for
symtabs ; it doesn ' t hurt to check . */
/* Was NAME already seen? */
if ( filename_seen ( name , 1 , first ) )
{
/* Yes; don't print it again. */
return ;
}
/* No; print it and reset *FIRST. */
1999-04-16 01:35:26 +00:00
if ( * first )
{
* first = 0 ;
}
else
{
printf_filtered ( " , " ) ;
}
wrap_here ( " " ) ;
fputs_filtered ( name , gdb_stdout ) ;
1999-07-07 20:19:36 +00:00
}
1999-04-16 01:35:26 +00:00
static void
2000-07-30 01:48:28 +00:00
sources_info ( char * ignore , int from_tty )
1999-04-16 01:35:26 +00:00
{
register struct symtab * s ;
register struct partial_symtab * ps ;
register struct objfile * objfile ;
int first ;
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
if ( ! have_full_symbols ( ) & & ! have_partial_symbols ( ) )
{
2000-11-19 17:27:38 +00:00
error ( " No symbol table is loaded. Use the \" file \" command. " ) ;
1999-04-16 01:35:26 +00:00
}
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
printf_filtered ( " Source files for which symbols have been read in: \n \n " ) ;
first = 1 ;
ALL_SYMTABS ( objfile , s )
1999-07-07 20:19:36 +00:00
{
output_source_filename ( s - > filename , & first ) ;
}
1999-04-16 01:35:26 +00:00
printf_filtered ( " \n \n " ) ;
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
printf_filtered ( " Source files for which symbols will be read in on demand: \n \n " ) ;
first = 1 ;
ALL_PSYMTABS ( objfile , ps )
1999-07-07 20:19:36 +00:00
{
if ( ! ps - > readin )
{
output_source_filename ( ps - > filename , & first ) ;
}
}
1999-04-16 01:35:26 +00:00
printf_filtered ( " \n " ) ;
}
static int
2000-10-28 22:15:09 +00:00
file_matches ( char * file , char * files [ ] , int nfiles )
1999-04-16 01:35:26 +00:00
{
int i ;
if ( file ! = NULL & & nfiles ! = 0 )
{
for ( i = 0 ; i < nfiles ; i + + )
1999-07-07 20:19:36 +00:00
{
2001-06-13 18:30:07 +00:00
if ( strcmp ( files [ i ] , lbasename ( file ) ) = = 0 )
1999-07-07 20:19:36 +00:00
return 1 ;
}
1999-04-16 01:35:26 +00:00
}
else if ( nfiles = = 0 )
return 1 ;
return 0 ;
}
/* Free any memory associated with a search. */
void
2000-07-30 01:48:28 +00:00
free_search_symbols ( struct symbol_search * symbols )
1999-04-16 01:35:26 +00:00
{
struct symbol_search * p ;
struct symbol_search * next ;
for ( p = symbols ; p ! = NULL ; p = next )
{
next = p - > next ;
2000-12-15 01:01:51 +00:00
xfree ( p ) ;
1999-04-16 01:35:26 +00:00
}
}
2000-05-29 13:18:15 +00:00
static void
do_free_search_symbols_cleanup ( void * symbols )
{
free_search_symbols ( symbols ) ;
}
struct cleanup *
make_cleanup_free_search_symbols ( struct symbol_search * symbols )
{
return make_cleanup ( do_free_search_symbols_cleanup , symbols ) ;
}
2002-02-11 03:21:53 +00:00
/* Helper function for sort_search_symbols and qsort. Can only
sort symbols , not minimal symbols . */
static int
compare_search_syms ( const void * sa , const void * sb )
{
struct symbol_search * * sym_a = ( struct symbol_search * * ) sa ;
struct symbol_search * * sym_b = ( struct symbol_search * * ) sb ;
return strcmp ( SYMBOL_SOURCE_NAME ( ( * sym_a ) - > symbol ) ,
SYMBOL_SOURCE_NAME ( ( * sym_b ) - > symbol ) ) ;
}
/* Sort the ``nfound'' symbols in the list after prevtail. Leave
prevtail where it is , but update its next pointer to point to
the first of the sorted symbols . */
static struct symbol_search *
sort_search_symbols ( struct symbol_search * prevtail , int nfound )
{
struct symbol_search * * symbols , * symp , * old_next ;
int i ;
symbols = ( struct symbol_search * * ) xmalloc ( sizeof ( struct symbol_search * )
* nfound ) ;
symp = prevtail - > next ;
for ( i = 0 ; i < nfound ; i + + )
{
symbols [ i ] = symp ;
symp = symp - > next ;
}
/* Generally NULL. */
old_next = symp ;
qsort ( symbols , nfound , sizeof ( struct symbol_search * ) ,
compare_search_syms ) ;
symp = prevtail ;
for ( i = 0 ; i < nfound ; i + + )
{
symp - > next = symbols [ i ] ;
symp = symp - > next ;
}
symp - > next = old_next ;
2002-02-24 01:44:00 +00:00
xfree ( symbols ) ;
2002-02-11 03:21:53 +00:00
return symp ;
}
2000-05-29 13:18:15 +00:00
1999-04-16 01:35:26 +00:00
/* Search the symbol table for matches to the regular expression REGEXP,
returning the results in * MATCHES .
Only symbols of KIND are searched :
1999-07-07 20:19:36 +00:00
FUNCTIONS_NAMESPACE - search all functions
TYPES_NAMESPACE - search all type names
METHODS_NAMESPACE - search all methods NOT IMPLEMENTED
VARIABLES_NAMESPACE - search all symbols , excluding functions , type names ,
and constants ( enums )
1999-04-16 01:35:26 +00:00
free_search_symbols should be called when * MATCHES is no longer needed .
2002-02-11 03:21:53 +00:00
The results are sorted locally ; each symtab ' s global and static blocks are
separately alphabetized .
1999-07-07 20:19:36 +00:00
*/
1999-04-16 01:35:26 +00:00
void
2000-10-28 22:15:09 +00:00
search_symbols ( char * regexp , namespace_enum kind , int nfiles , char * files [ ] ,
struct symbol_search * * matches )
1999-04-16 01:35:26 +00:00
{
register struct symtab * s ;
register struct partial_symtab * ps ;
register struct blockvector * bv ;
struct blockvector * prev_bv = 0 ;
register struct block * b ;
register int i = 0 ;
register int j ;
register struct symbol * sym ;
struct partial_symbol * * psym ;
struct objfile * objfile ;
struct minimal_symbol * msymbol ;
char * val ;
int found_misc = 0 ;
static enum minimal_symbol_type types [ ]
1999-07-07 20:19:36 +00:00
=
{ mst_data , mst_text , mst_abs , mst_unknown } ;
1999-04-16 01:35:26 +00:00
static enum minimal_symbol_type types2 [ ]
1999-07-07 20:19:36 +00:00
=
{ mst_bss , mst_file_text , mst_abs , mst_unknown } ;
1999-04-16 01:35:26 +00:00
static enum minimal_symbol_type types3 [ ]
1999-07-07 20:19:36 +00:00
=
{ mst_file_data , mst_solib_trampoline , mst_abs , mst_unknown } ;
1999-04-16 01:35:26 +00:00
static enum minimal_symbol_type types4 [ ]
1999-07-07 20:19:36 +00:00
=
{ mst_file_bss , mst_text , mst_abs , mst_unknown } ;
1999-04-16 01:35:26 +00:00
enum minimal_symbol_type ourtype ;
enum minimal_symbol_type ourtype2 ;
enum minimal_symbol_type ourtype3 ;
enum minimal_symbol_type ourtype4 ;
struct symbol_search * sr ;
struct symbol_search * psr ;
struct symbol_search * tail ;
struct cleanup * old_chain = NULL ;
2001-02-27 21:57:09 +00:00
if ( kind < VARIABLES_NAMESPACE )
1999-04-16 01:35:26 +00:00
error ( " must search on specific namespace " ) ;
2000-08-25 20:51:19 +00:00
ourtype = types [ ( int ) ( kind - VARIABLES_NAMESPACE ) ] ;
ourtype2 = types2 [ ( int ) ( kind - VARIABLES_NAMESPACE ) ] ;
ourtype3 = types3 [ ( int ) ( kind - VARIABLES_NAMESPACE ) ] ;
ourtype4 = types4 [ ( int ) ( kind - VARIABLES_NAMESPACE ) ] ;
1999-04-16 01:35:26 +00:00
sr = * matches = NULL ;
tail = NULL ;
if ( regexp ! = NULL )
{
/* Make sure spacing is right for C++ operators.
This is just a courtesy to make the matching less sensitive
to how many spaces the user leaves between ' operator '
and < TYPENAME > or < OPERATOR > . */
char * opend ;
char * opname = operator_chars ( regexp , & opend ) ;
if ( * opname )
1999-07-07 20:19:36 +00:00
{
int fix = - 1 ; /* -1 means ok; otherwise number of spaces needed. */
if ( isalpha ( * opname ) | | * opname = = ' _ ' | | * opname = = ' $ ' )
{
/* There should 1 space between 'operator' and 'TYPENAME'. */
if ( opname [ - 1 ] ! = ' ' | | opname [ - 2 ] = = ' ' )
fix = 1 ;
}
else
{
/* There should 0 spaces between 'operator' and 'OPERATOR'. */
if ( opname [ - 1 ] = = ' ' )
fix = 0 ;
}
/* If wrong number of spaces, fix it. */
if ( fix > = 0 )
{
2001-12-03 19:30:39 +00:00
char * tmp = ( char * ) alloca ( 8 + fix + strlen ( opname ) + 1 ) ;
1999-07-07 20:19:36 +00:00
sprintf ( tmp , " operator%.*s%s " , fix , " " , opname ) ;
regexp = tmp ;
}
}
1999-04-16 01:35:26 +00:00
if ( 0 ! = ( val = re_comp ( regexp ) ) )
1999-07-07 20:19:36 +00:00
error ( " Invalid regexp (%s): %s " , val , regexp ) ;
1999-04-16 01:35:26 +00:00
}
/* Search through the partial symtabs *first* for all symbols
matching the regexp . That way we don ' t have to reproduce all of
the machinery below . */
ALL_PSYMTABS ( objfile , ps )
1999-07-07 20:19:36 +00:00
{
struct partial_symbol * * bound , * * gbound , * * sbound ;
int keep_going = 1 ;
if ( ps - > readin )
continue ;
gbound = objfile - > global_psymbols . list + ps - > globals_offset + ps - > n_global_syms ;
sbound = objfile - > static_psymbols . list + ps - > statics_offset + ps - > n_static_syms ;
bound = gbound ;
/* Go through all of the symbols stored in a partial
symtab in one loop . */
psym = objfile - > global_psymbols . list + ps - > globals_offset ;
while ( keep_going )
{
if ( psym > = bound )
{
if ( bound = = gbound & & ps - > n_static_syms ! = 0 )
{
psym = objfile - > static_psymbols . list + ps - > statics_offset ;
bound = sbound ;
}
else
keep_going = 0 ;
continue ;
}
else
{
QUIT ;
/* If it would match (logic taken from loop below)
load the file and go on to the next one */
if ( file_matches ( ps - > filename , files , nfiles )
& & ( ( regexp = = NULL | | SYMBOL_MATCHES_REGEXP ( * psym ) )
& & ( ( kind = = VARIABLES_NAMESPACE & & SYMBOL_CLASS ( * psym ) ! = LOC_TYPEDEF
& & SYMBOL_CLASS ( * psym ) ! = LOC_BLOCK )
| | ( kind = = FUNCTIONS_NAMESPACE & & SYMBOL_CLASS ( * psym ) = = LOC_BLOCK )
| | ( kind = = TYPES_NAMESPACE & & SYMBOL_CLASS ( * psym ) = = LOC_TYPEDEF )
| | ( kind = = METHODS_NAMESPACE & & SYMBOL_CLASS ( * psym ) = = LOC_BLOCK ) ) ) )
{
PSYMTAB_TO_SYMTAB ( ps ) ;
keep_going = 0 ;
}
}
psym + + ;
}
}
1999-04-16 01:35:26 +00:00
/* Here, we search through the minimal symbol tables for functions
and variables that match , and force their symbols to be read .
This is in particular necessary for demangled variable names ,
which are no longer put into the partial symbol tables .
The symbol will then be found during the scan of symtabs below .
For functions , find_pc_symtab should succeed if we have debug info
for the function , for variables we have to call lookup_symbol
to determine if the variable has debug info .
If the lookup fails , set found_misc so that we will rescan to print
any matching symbols without debug info .
1999-07-07 20:19:36 +00:00
*/
1999-04-16 01:35:26 +00:00
if ( nfiles = = 0 & & ( kind = = VARIABLES_NAMESPACE | | kind = = FUNCTIONS_NAMESPACE ) )
{
ALL_MSYMBOLS ( objfile , msymbol )
1999-07-07 20:19:36 +00:00
{
if ( MSYMBOL_TYPE ( msymbol ) = = ourtype | |
MSYMBOL_TYPE ( msymbol ) = = ourtype2 | |
MSYMBOL_TYPE ( msymbol ) = = ourtype3 | |
MSYMBOL_TYPE ( msymbol ) = = ourtype4 )
{
if ( regexp = = NULL | | SYMBOL_MATCHES_REGEXP ( msymbol ) )
{
if ( 0 = = find_pc_symtab ( SYMBOL_VALUE_ADDRESS ( msymbol ) ) )
{
if ( kind = = FUNCTIONS_NAMESPACE
| | lookup_symbol ( SYMBOL_NAME ( msymbol ) ,
( struct block * ) NULL ,
VAR_NAMESPACE ,
0 , ( struct symtab * * ) NULL ) = = NULL )
found_misc = 1 ;
}
}
}
}
1999-04-16 01:35:26 +00:00
}
ALL_SYMTABS ( objfile , s )
1999-07-07 20:19:36 +00:00
{
bv = BLOCKVECTOR ( s ) ;
/* Often many files share a blockvector.
Scan each blockvector only once so that
we don ' t get every symbol many times .
It happens that the first symtab in the list
for any given blockvector is the main file . */
if ( bv ! = prev_bv )
for ( i = GLOBAL_BLOCK ; i < = STATIC_BLOCK ; i + + )
{
2002-02-11 03:21:53 +00:00
struct symbol_search * prevtail = tail ;
int nfound = 0 ;
1999-07-07 20:19:36 +00:00
b = BLOCKVECTOR_BLOCK ( bv , i ) ;
2002-07-11 20:46:19 +00:00
ALL_BLOCK_SYMBOLS ( b , j , sym )
1999-07-07 20:19:36 +00:00
{
QUIT ;
if ( file_matches ( s - > filename , files , nfiles )
& & ( ( regexp = = NULL | | SYMBOL_MATCHES_REGEXP ( sym ) )
& & ( ( kind = = VARIABLES_NAMESPACE & & SYMBOL_CLASS ( sym ) ! = LOC_TYPEDEF
& & SYMBOL_CLASS ( sym ) ! = LOC_BLOCK
& & SYMBOL_CLASS ( sym ) ! = LOC_CONST )
| | ( kind = = FUNCTIONS_NAMESPACE & & SYMBOL_CLASS ( sym ) = = LOC_BLOCK )
| | ( kind = = TYPES_NAMESPACE & & SYMBOL_CLASS ( sym ) = = LOC_TYPEDEF )
| | ( kind = = METHODS_NAMESPACE & & SYMBOL_CLASS ( sym ) = = LOC_BLOCK ) ) ) )
{
/* match */
psr = ( struct symbol_search * ) xmalloc ( sizeof ( struct symbol_search ) ) ;
psr - > block = i ;
psr - > symtab = s ;
psr - > symbol = sym ;
psr - > msymbol = NULL ;
psr - > next = NULL ;
if ( tail = = NULL )
2002-02-11 03:21:53 +00:00
sr = psr ;
1999-07-07 20:19:36 +00:00
else
tail - > next = psr ;
tail = psr ;
2002-02-11 03:21:53 +00:00
nfound + + ;
}
}
if ( nfound > 0 )
{
if ( prevtail = = NULL )
{
struct symbol_search dummy ;
dummy . next = sr ;
tail = sort_search_symbols ( & dummy , nfound ) ;
sr = dummy . next ;
old_chain = make_cleanup_free_search_symbols ( sr ) ;
1999-07-07 20:19:36 +00:00
}
2002-02-11 03:21:53 +00:00
else
tail = sort_search_symbols ( prevtail , nfound ) ;
1999-07-07 20:19:36 +00:00
}
}
prev_bv = bv ;
}
1999-04-16 01:35:26 +00:00
/* If there are no eyes, avoid all contact. I mean, if there are
no debug symbols , then print directly from the msymbol_vector . */
if ( found_misc | | kind ! = FUNCTIONS_NAMESPACE )
{
ALL_MSYMBOLS ( objfile , msymbol )
1999-07-07 20:19:36 +00:00
{
if ( MSYMBOL_TYPE ( msymbol ) = = ourtype | |
MSYMBOL_TYPE ( msymbol ) = = ourtype2 | |
MSYMBOL_TYPE ( msymbol ) = = ourtype3 | |
MSYMBOL_TYPE ( msymbol ) = = ourtype4 )
{
if ( regexp = = NULL | | SYMBOL_MATCHES_REGEXP ( msymbol ) )
{
/* Functions: Look up by address. */
if ( kind ! = FUNCTIONS_NAMESPACE | |
( 0 = = find_pc_symtab ( SYMBOL_VALUE_ADDRESS ( msymbol ) ) ) )
{
/* Variables/Absolutes: Look up by name */
if ( lookup_symbol ( SYMBOL_NAME ( msymbol ) ,
( struct block * ) NULL , VAR_NAMESPACE ,
0 , ( struct symtab * * ) NULL ) = = NULL )
{
/* match */
psr = ( struct symbol_search * ) xmalloc ( sizeof ( struct symbol_search ) ) ;
psr - > block = i ;
psr - > msymbol = msymbol ;
psr - > symtab = NULL ;
psr - > symbol = NULL ;
psr - > next = NULL ;
if ( tail = = NULL )
{
sr = psr ;
2000-05-29 13:18:15 +00:00
old_chain = make_cleanup_free_search_symbols ( sr ) ;
1999-07-07 20:19:36 +00:00
}
else
tail - > next = psr ;
tail = psr ;
}
}
}
}
}
1999-04-16 01:35:26 +00:00
}
* matches = sr ;
if ( sr ! = NULL )
discard_cleanups ( old_chain ) ;
}
/* Helper function for symtab_symbol_info, this function uses
the data returned from search_symbols ( ) to print information
regarding the match to gdb_stdout .
1999-07-07 20:19:36 +00:00
*/
1999-04-16 01:35:26 +00:00
static void
2000-07-30 01:48:28 +00:00
print_symbol_info ( namespace_enum kind , struct symtab * s , struct symbol * sym ,
int block , char * last )
1999-04-16 01:35:26 +00:00
{
if ( last = = NULL | | strcmp ( last , s - > filename ) ! = 0 )
{
fputs_filtered ( " \n File " , gdb_stdout ) ;
fputs_filtered ( s - > filename , gdb_stdout ) ;
fputs_filtered ( " : \n " , gdb_stdout ) ;
}
if ( kind ! = TYPES_NAMESPACE & & block = = STATIC_BLOCK )
printf_filtered ( " static " ) ;
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
/* Typedef that is not a C++ class */
if ( kind = = TYPES_NAMESPACE
& & SYMBOL_NAMESPACE ( sym ) ! = STRUCT_NAMESPACE )
2000-09-04 08:29:25 +00:00
typedef_print ( SYMBOL_TYPE ( sym ) , sym , gdb_stdout ) ;
1999-04-16 01:35:26 +00:00
/* variable, func, or typedef-that-is-c++-class */
1999-07-07 20:19:36 +00:00
else if ( kind < TYPES_NAMESPACE | |
( kind = = TYPES_NAMESPACE & &
SYMBOL_NAMESPACE ( sym ) = = STRUCT_NAMESPACE ) )
1999-04-16 01:35:26 +00:00
{
type_print ( SYMBOL_TYPE ( sym ) ,
1999-07-07 20:19:36 +00:00
( SYMBOL_CLASS ( sym ) = = LOC_TYPEDEF
? " " : SYMBOL_SOURCE_NAME ( sym ) ) ,
gdb_stdout , 0 ) ;
1999-04-16 01:35:26 +00:00
printf_filtered ( " ; \n " ) ;
}
}
/* This help function for symtab_symbol_info() prints information
for non - debugging symbols to gdb_stdout .
1999-07-07 20:19:36 +00:00
*/
1999-04-16 01:35:26 +00:00
static void
2000-07-30 01:48:28 +00:00
print_msymbol_info ( struct minimal_symbol * msymbol )
1999-04-16 01:35:26 +00:00
{
2001-05-11 17:48:31 +00:00
char * tmp ;
if ( TARGET_ADDR_BIT < = 32 )
2002-05-12 04:20:06 +00:00
tmp = local_hex_string_custom ( SYMBOL_VALUE_ADDRESS ( msymbol )
& ( CORE_ADDR ) 0xffffffff ,
" 08l " ) ;
2001-05-11 17:48:31 +00:00
else
2002-05-12 04:20:06 +00:00
tmp = local_hex_string_custom ( SYMBOL_VALUE_ADDRESS ( msymbol ) ,
" 016l " ) ;
2001-05-11 17:48:31 +00:00
printf_filtered ( " %s %s \n " ,
tmp , SYMBOL_SOURCE_NAME ( msymbol ) ) ;
1999-04-16 01:35:26 +00:00
}
/* This is the guts of the commands "info functions", "info types", and
" info variables " . It calls search_symbols to find all matches and then
print_ [ m ] symbol_info to print out some useful information about the
matches .
1999-07-07 20:19:36 +00:00
*/
1999-04-16 01:35:26 +00:00
static void
2000-07-30 01:48:28 +00:00
symtab_symbol_info ( char * regexp , namespace_enum kind , int from_tty )
1999-04-16 01:35:26 +00:00
{
static char * classnames [ ]
1999-07-07 20:19:36 +00:00
=
{ " variable " , " function " , " type " , " method " } ;
1999-04-16 01:35:26 +00:00
struct symbol_search * symbols ;
struct symbol_search * p ;
struct cleanup * old_chain ;
char * last_filename = NULL ;
int first = 1 ;
/* must make sure that if we're interrupted, symbols gets freed */
search_symbols ( regexp , kind , 0 , ( char * * ) NULL , & symbols ) ;
2000-05-29 13:18:15 +00:00
old_chain = make_cleanup_free_search_symbols ( symbols ) ;
1999-04-16 01:35:26 +00:00
printf_filtered ( regexp
1999-07-07 20:19:36 +00:00
? " All %ss matching regular expression \" %s \" : \n "
: " All defined %ss: \n " ,
2000-08-25 20:51:19 +00:00
classnames [ ( int ) ( kind - VARIABLES_NAMESPACE ) ] , regexp ) ;
1999-04-16 01:35:26 +00:00
for ( p = symbols ; p ! = NULL ; p = p - > next )
{
QUIT ;
if ( p - > msymbol ! = NULL )
1999-07-07 20:19:36 +00:00
{
if ( first )
{
printf_filtered ( " \n Non-debugging symbols: \n " ) ;
first = 0 ;
}
print_msymbol_info ( p - > msymbol ) ;
}
1999-04-16 01:35:26 +00:00
else
1999-07-07 20:19:36 +00:00
{
print_symbol_info ( kind ,
p - > symtab ,
p - > symbol ,
p - > block ,
last_filename ) ;
last_filename = p - > symtab - > filename ;
}
1999-04-16 01:35:26 +00:00
}
do_cleanups ( old_chain ) ;
}
static void
2000-07-30 01:48:28 +00:00
variables_info ( char * regexp , int from_tty )
1999-04-16 01:35:26 +00:00
{
symtab_symbol_info ( regexp , VARIABLES_NAMESPACE , from_tty ) ;
}
static void
2000-07-30 01:48:28 +00:00
functions_info ( char * regexp , int from_tty )
1999-04-16 01:35:26 +00:00
{
symtab_symbol_info ( regexp , FUNCTIONS_NAMESPACE , from_tty ) ;
}
2000-06-05 20:49:53 +00:00
1999-04-16 01:35:26 +00:00
static void
2000-07-30 01:48:28 +00:00
types_info ( char * regexp , int from_tty )
1999-04-16 01:35:26 +00:00
{
symtab_symbol_info ( regexp , TYPES_NAMESPACE , from_tty ) ;
}
/* Breakpoint all functions matching regular expression. */
2002-01-17 22:15:18 +00:00
2000-02-03 04:14:45 +00:00
void
2000-07-30 01:48:28 +00:00
rbreak_command_wrapper ( char * regexp , int from_tty )
2000-02-03 04:14:45 +00:00
{
rbreak_command ( regexp , from_tty ) ;
}
2002-01-17 22:15:18 +00:00
1999-04-16 01:35:26 +00:00
static void
2000-07-30 01:48:28 +00:00
rbreak_command ( char * regexp , int from_tty )
1999-04-16 01:35:26 +00:00
{
struct symbol_search * ss ;
struct symbol_search * p ;
struct cleanup * old_chain ;
search_symbols ( regexp , FUNCTIONS_NAMESPACE , 0 , ( char * * ) NULL , & ss ) ;
2000-05-29 13:18:15 +00:00
old_chain = make_cleanup_free_search_symbols ( ss ) ;
1999-04-16 01:35:26 +00:00
for ( p = ss ; p ! = NULL ; p = p - > next )
{
if ( p - > msymbol = = NULL )
1999-07-07 20:19:36 +00:00
{
char * string = ( char * ) alloca ( strlen ( p - > symtab - > filename )
+ strlen ( SYMBOL_NAME ( p - > symbol ) )
+ 4 ) ;
strcpy ( string , p - > symtab - > filename ) ;
strcat ( string , " :' " ) ;
strcat ( string , SYMBOL_NAME ( p - > symbol ) ) ;
strcat ( string , " ' " ) ;
break_command ( string , from_tty ) ;
print_symbol_info ( FUNCTIONS_NAMESPACE ,
p - > symtab ,
p - > symbol ,
p - > block ,
p - > symtab - > filename ) ;
}
1999-04-16 01:35:26 +00:00
else
1999-07-07 20:19:36 +00:00
{
break_command ( SYMBOL_NAME ( p - > msymbol ) , from_tty ) ;
printf_filtered ( " <function, no debug info> %s; \n " ,
SYMBOL_SOURCE_NAME ( p - > msymbol ) ) ;
}
1999-04-16 01:35:26 +00:00
}
do_cleanups ( old_chain ) ;
}
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
/* Return Nonzero if block a is lexically nested within block b,
or if a and b have the same pc range .
Return zero otherwise . */
int
2000-07-30 01:48:28 +00:00
contained_in ( struct block * a , struct block * b )
1999-04-16 01:35:26 +00:00
{
if ( ! a | | ! b )
return 0 ;
return BLOCK_START ( a ) > = BLOCK_START ( b )
1999-07-07 20:19:36 +00:00
& & BLOCK_END ( a ) < = BLOCK_END ( b ) ;
1999-04-16 01:35:26 +00:00
}
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
/* Helper routine for make_symbol_completion_list. */
static int return_val_size ;
static int return_val_index ;
static char * * return_val ;
# define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \
do { \
if ( SYMBOL_DEMANGLED_NAME ( symbol ) ! = NULL ) \
/* Put only the mangled name on the list. */ \
/* Advantage: "b foo<TAB>" completes to "b foo(int, int)" */ \
/* Disadvantage: "b foo__i<TAB>" doesn't complete. */ \
completion_list_add_name \
( SYMBOL_DEMANGLED_NAME ( symbol ) , ( sym_text ) , ( len ) , ( text ) , ( word ) ) ; \
else \
completion_list_add_name \
( SYMBOL_NAME ( symbol ) , ( sym_text ) , ( len ) , ( text ) , ( word ) ) ; \
} while ( 0 )
/* Test to see if the symbol specified by SYMNAME (which is already
1999-07-07 20:19:36 +00:00
demangled for C + + symbols ) matches SYM_TEXT in the first SYM_TEXT_LEN
characters . If so , add it to the current completion list . */
1999-04-16 01:35:26 +00:00
static void
2000-07-30 01:48:28 +00:00
completion_list_add_name ( char * symname , char * sym_text , int sym_text_len ,
char * text , char * word )
1999-04-16 01:35:26 +00:00
{
int newsize ;
int i ;
/* clip symbols that cannot match */
if ( strncmp ( symname , sym_text , sym_text_len ) ! = 0 )
{
return ;
}
/* We have a match for a completion, so add SYMNAME to the current list
of matches . Note that the name is moved to freshly malloc ' d space . */
{
char * new ;
if ( word = = sym_text )
{
new = xmalloc ( strlen ( symname ) + 5 ) ;
strcpy ( new , symname ) ;
}
else if ( word > sym_text )
{
/* Return some portion of symname. */
new = xmalloc ( strlen ( symname ) + 5 ) ;
strcpy ( new , symname + ( word - sym_text ) ) ;
}
else
{
/* Return some of SYM_TEXT plus symname. */
new = xmalloc ( strlen ( symname ) + ( sym_text - word ) + 5 ) ;
strncpy ( new , word , sym_text - word ) ;
new [ sym_text - word ] = ' \0 ' ;
strcat ( new , symname ) ;
}
if ( return_val_index + 3 > return_val_size )
{
newsize = ( return_val_size * = 2 ) * sizeof ( char * ) ;
return_val = ( char * * ) xrealloc ( ( char * ) return_val , newsize ) ;
}
return_val [ return_val_index + + ] = new ;
return_val [ return_val_index ] = NULL ;
}
}
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
/* Return a NULL terminated array of all symbols (regardless of class)
which begin by matching TEXT . If the answer is no symbols , then
the return value is an array which contains only a NULL pointer .
1999-04-16 01:35:26 +00:00
Problem : All of the symbols have to be copied because readline frees them .
I ' m not going to worry about this ; hopefully there won ' t be that many . */
char * *
2000-07-30 01:48:28 +00:00
make_symbol_completion_list ( char * text , char * word )
1999-04-16 01:35:26 +00:00
{
register struct symbol * sym ;
register struct symtab * s ;
register struct partial_symtab * ps ;
register struct minimal_symbol * msymbol ;
register struct objfile * objfile ;
register struct block * b , * surrounding_static_block = 0 ;
register int i , j ;
struct partial_symbol * * psym ;
/* The symbol we are completing on. Points in same buffer as text. */
char * sym_text ;
/* Length of sym_text. */
int sym_text_len ;
/* Now look for the symbol we are supposed to complete on.
FIXME : This should be language - specific . */
{
char * p ;
char quote_found ;
char * quote_pos = NULL ;
/* First see if this is a quoted string. */
quote_found = ' \0 ' ;
for ( p = text ; * p ! = ' \0 ' ; + + p )
{
if ( quote_found ! = ' \0 ' )
{
if ( * p = = quote_found )
/* Found close quote. */
quote_found = ' \0 ' ;
else if ( * p = = ' \\ ' & & p [ 1 ] = = quote_found )
/* A backslash followed by the quote character
1999-07-07 20:19:36 +00:00
doesn ' t end the string . */
1999-04-16 01:35:26 +00:00
+ + p ;
}
else if ( * p = = ' \' ' | | * p = = ' " ' )
{
quote_found = * p ;
quote_pos = p ;
}
}
if ( quote_found = = ' \' ' )
/* A string within single quotes can be a symbol, so complete on it. */
sym_text = quote_pos + 1 ;
else if ( quote_found = = ' " ' )
/* A double-quoted string is never a symbol, nor does it make sense
1999-07-07 20:19:36 +00:00
to complete it any other way . */
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
{
return_val = ( char * * ) xmalloc ( sizeof ( char * ) ) ;
return_val [ 0 ] = NULL ;
return return_val ;
}
1999-04-16 01:35:26 +00:00
else
{
/* It is not a quoted string. Break it based on the characters
which are in symbols . */
while ( p > text )
{
if ( isalnum ( p [ - 1 ] ) | | p [ - 1 ] = = ' _ ' | | p [ - 1 ] = = ' \0 ' )
- - p ;
else
break ;
}
sym_text = p ;
}
}
sym_text_len = strlen ( sym_text ) ;
return_val_size = 100 ;
return_val_index = 0 ;
return_val = ( char * * ) xmalloc ( ( return_val_size + 1 ) * sizeof ( char * ) ) ;
return_val [ 0 ] = NULL ;
/* Look through the partial symtabs for all symbols which begin
by matching SYM_TEXT . Add each one that you find to the list . */
ALL_PSYMTABS ( objfile , ps )
1999-07-07 20:19:36 +00:00
{
/* If the psymtab's been read in we'll get it when we search
through the blockvector . */
if ( ps - > readin )
continue ;
for ( psym = objfile - > global_psymbols . list + ps - > globals_offset ;
psym < ( objfile - > global_psymbols . list + ps - > globals_offset
+ ps - > n_global_syms ) ;
psym + + )
{
/* If interrupted, then quit. */
QUIT ;
COMPLETION_LIST_ADD_SYMBOL ( * psym , sym_text , sym_text_len , text , word ) ;
}
for ( psym = objfile - > static_psymbols . list + ps - > statics_offset ;
psym < ( objfile - > static_psymbols . list + ps - > statics_offset
+ ps - > n_static_syms ) ;
psym + + )
{
QUIT ;
COMPLETION_LIST_ADD_SYMBOL ( * psym , sym_text , sym_text_len , text , word ) ;
}
}
1999-04-16 01:35:26 +00:00
/* At this point scan through the misc symbol vectors and add each
symbol you find to the list . Eventually we want to ignore
anything that isn ' t a text symbol ( everything else will be
handled by the psymtab code above ) . */
ALL_MSYMBOLS ( objfile , msymbol )
1999-07-07 20:19:36 +00:00
{
QUIT ;
COMPLETION_LIST_ADD_SYMBOL ( msymbol , sym_text , sym_text_len , text , word ) ;
}
1999-04-16 01:35:26 +00:00
/* Search upwards from currently selected frame (so that we can
complete on local vars . */
gdb/ChangeLog:
* stack.c (get_selected_block): Add new argument `addr_in_block',
used to return the exact code address we used to select the block,
not just the block.
* blockframe.c (get_frame_block, get_current_block): Same.
* frame.h (get_frame_block, get_current_block,
get_selected_block): Update declarations.
* linespec.c, stack.c, blockframe.c, breakpoint.c, findvar.c,
linespec.c, varobj.c, printcmd.c, symtab.c: Callers changed.
gdb/mi/ChangeLog:
* mi-cmd-stack.c (list_args_or_locals): Pass new arg to
get_frame_block. (See entry in gdb/ChangeLog.)
2002-04-05 22:04:43 +00:00
for ( b = get_selected_block ( 0 ) ; b ! = NULL ; b = BLOCK_SUPERBLOCK ( b ) )
1999-04-16 01:35:26 +00:00
{
if ( ! BLOCK_SUPERBLOCK ( b ) )
{
1999-07-07 20:19:36 +00:00
surrounding_static_block = b ; /* For elmin of dups */
1999-04-16 01:35:26 +00:00
}
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
/* Also catch fields of types defined in this places which match our
1999-07-07 20:19:36 +00:00
text string . Only complete on types visible from current context . */
1999-04-16 01:35:26 +00:00
2001-10-12 23:51:30 +00:00
ALL_BLOCK_SYMBOLS ( b , i , sym )
1999-04-16 01:35:26 +00:00
{
COMPLETION_LIST_ADD_SYMBOL ( sym , sym_text , sym_text_len , text , word ) ;
if ( SYMBOL_CLASS ( sym ) = = LOC_TYPEDEF )
{
struct type * t = SYMBOL_TYPE ( sym ) ;
enum type_code c = TYPE_CODE ( t ) ;
if ( c = = TYPE_CODE_UNION | | c = = TYPE_CODE_STRUCT )
{
for ( j = TYPE_N_BASECLASSES ( t ) ; j < TYPE_NFIELDS ( t ) ; j + + )
{
if ( TYPE_FIELD_NAME ( t , j ) )
{
completion_list_add_name ( TYPE_FIELD_NAME ( t , j ) ,
1999-07-07 20:19:36 +00:00
sym_text , sym_text_len , text , word ) ;
1999-04-16 01:35:26 +00:00
}
}
}
}
}
}
/* Go through the symtabs and check the externs and statics for
symbols which match . */
ALL_SYMTABS ( objfile , s )
1999-07-07 20:19:36 +00:00
{
QUIT ;
b = BLOCKVECTOR_BLOCK ( BLOCKVECTOR ( s ) , GLOBAL_BLOCK ) ;
2001-10-12 23:51:30 +00:00
ALL_BLOCK_SYMBOLS ( b , i , sym )
1999-07-07 20:19:36 +00:00
{
COMPLETION_LIST_ADD_SYMBOL ( sym , sym_text , sym_text_len , text , word ) ;
}
}
1999-04-16 01:35:26 +00:00
ALL_SYMTABS ( objfile , s )
1999-07-07 20:19:36 +00:00
{
QUIT ;
b = BLOCKVECTOR_BLOCK ( BLOCKVECTOR ( s ) , STATIC_BLOCK ) ;
/* Don't do this block twice. */
if ( b = = surrounding_static_block )
continue ;
2001-10-12 23:51:30 +00:00
ALL_BLOCK_SYMBOLS ( b , i , sym )
1999-07-07 20:19:36 +00:00
{
COMPLETION_LIST_ADD_SYMBOL ( sym , sym_text , sym_text_len , text , word ) ;
}
}
1999-04-16 01:35:26 +00:00
return ( return_val ) ;
}
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
/* Like make_symbol_completion_list, but returns a list of symbols
defined in a source file FILE . */
char * *
make_file_symbol_completion_list ( char * text , char * word , char * srcfile )
{
register struct symbol * sym ;
register struct symtab * s ;
register struct block * b ;
register int i ;
/* The symbol we are completing on. Points in same buffer as text. */
char * sym_text ;
/* Length of sym_text. */
int sym_text_len ;
/* Now look for the symbol we are supposed to complete on.
FIXME : This should be language - specific . */
{
char * p ;
char quote_found ;
char * quote_pos = NULL ;
/* First see if this is a quoted string. */
quote_found = ' \0 ' ;
for ( p = text ; * p ! = ' \0 ' ; + + p )
{
if ( quote_found ! = ' \0 ' )
{
if ( * p = = quote_found )
/* Found close quote. */
quote_found = ' \0 ' ;
else if ( * p = = ' \\ ' & & p [ 1 ] = = quote_found )
/* A backslash followed by the quote character
doesn ' t end the string . */
+ + p ;
}
else if ( * p = = ' \' ' | | * p = = ' " ' )
{
quote_found = * p ;
quote_pos = p ;
}
}
if ( quote_found = = ' \' ' )
/* A string within single quotes can be a symbol, so complete on it. */
sym_text = quote_pos + 1 ;
else if ( quote_found = = ' " ' )
/* A double-quoted string is never a symbol, nor does it make sense
to complete it any other way . */
{
return_val = ( char * * ) xmalloc ( sizeof ( char * ) ) ;
return_val [ 0 ] = NULL ;
return return_val ;
}
else
{
/* It is not a quoted string. Break it based on the characters
which are in symbols . */
while ( p > text )
{
if ( isalnum ( p [ - 1 ] ) | | p [ - 1 ] = = ' _ ' | | p [ - 1 ] = = ' \0 ' )
- - p ;
else
break ;
}
sym_text = p ;
}
}
sym_text_len = strlen ( sym_text ) ;
return_val_size = 10 ;
return_val_index = 0 ;
return_val = ( char * * ) xmalloc ( ( return_val_size + 1 ) * sizeof ( char * ) ) ;
return_val [ 0 ] = NULL ;
/* Find the symtab for SRCFILE (this loads it if it was not yet read
in ) . */
s = lookup_symtab ( srcfile ) ;
if ( s = = NULL )
{
/* Maybe they typed the file with leading directories, while the
symbol tables record only its basename . */
2001-06-13 18:30:07 +00:00
const char * tail = lbasename ( srcfile ) ;
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
if ( tail > srcfile )
s = lookup_symtab ( tail ) ;
}
/* If we have no symtab for that file, return an empty list. */
if ( s = = NULL )
return ( return_val ) ;
/* Go through this symtab and check the externs and statics for
symbols which match . */
b = BLOCKVECTOR_BLOCK ( BLOCKVECTOR ( s ) , GLOBAL_BLOCK ) ;
2001-10-12 23:51:30 +00:00
ALL_BLOCK_SYMBOLS ( b , i , sym )
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
{
COMPLETION_LIST_ADD_SYMBOL ( sym , sym_text , sym_text_len , text , word ) ;
}
b = BLOCKVECTOR_BLOCK ( BLOCKVECTOR ( s ) , STATIC_BLOCK ) ;
2001-10-12 23:51:30 +00:00
ALL_BLOCK_SYMBOLS ( b , i , sym )
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
{
COMPLETION_LIST_ADD_SYMBOL ( sym , sym_text , sym_text_len , text , word ) ;
}
return ( return_val ) ;
}
/* A helper function for make_source_files_completion_list. It adds
another file name to a list of possible completions , growing the
list as necessary . */
static void
add_filename_to_list ( const char * fname , char * text , char * word ,
char * * * list , int * list_used , int * list_alloced )
{
char * new ;
size_t fnlen = strlen ( fname ) ;
if ( * list_used + 1 > = * list_alloced )
{
* list_alloced * = 2 ;
* list = ( char * * ) xrealloc ( ( char * ) * list ,
* list_alloced * sizeof ( char * ) ) ;
}
if ( word = = text )
{
/* Return exactly fname. */
new = xmalloc ( fnlen + 5 ) ;
strcpy ( new , fname ) ;
}
else if ( word > text )
{
/* Return some portion of fname. */
new = xmalloc ( fnlen + 5 ) ;
strcpy ( new , fname + ( word - text ) ) ;
}
else
{
/* Return some of TEXT plus fname. */
new = xmalloc ( fnlen + ( text - word ) + 5 ) ;
strncpy ( new , word , text - word ) ;
new [ text - word ] = ' \0 ' ;
strcat ( new , fname ) ;
}
( * list ) [ * list_used ] = new ;
( * list ) [ + + * list_used ] = NULL ;
}
static int
not_interesting_fname ( const char * fname )
{
static const char * illegal_aliens [ ] = {
" _globals_ " , /* inserted by coff_symtab_read */
NULL
} ;
int i ;
for ( i = 0 ; illegal_aliens [ i ] ; i + + )
{
if ( strcmp ( fname , illegal_aliens [ i ] ) = = 0 )
return 1 ;
}
return 0 ;
}
/* Return a NULL terminated array of all source files whose names
begin with matching TEXT . The file names are looked up in the
symbol tables of this program . If the answer is no matchess , then
the return value is an array which contains only a NULL pointer . */
char * *
make_source_files_completion_list ( char * text , char * word )
{
register struct symtab * s ;
register struct partial_symtab * ps ;
register struct objfile * objfile ;
int first = 1 ;
int list_alloced = 1 ;
int list_used = 0 ;
size_t text_len = strlen ( text ) ;
char * * list = ( char * * ) xmalloc ( list_alloced * sizeof ( char * ) ) ;
2001-06-13 18:30:07 +00:00
const char * base_name ;
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
list [ 0 ] = NULL ;
if ( ! have_full_symbols ( ) & & ! have_partial_symbols ( ) )
return list ;
ALL_SYMTABS ( objfile , s )
{
if ( not_interesting_fname ( s - > filename ) )
continue ;
if ( ! filename_seen ( s - > filename , 1 , & first )
# if HAVE_DOS_BASED_FILE_SYSTEM
& & strncasecmp ( s - > filename , text , text_len ) = = 0
# else
& & strncmp ( s - > filename , text , text_len ) = = 0
# endif
)
{
/* This file matches for a completion; add it to the current
list of matches . */
add_filename_to_list ( s - > filename , text , word ,
& list , & list_used , & list_alloced ) ;
}
else
{
/* NOTE: We allow the user to type a base name when the
debug info records leading directories , but not the other
way around . This is what subroutines of breakpoint
command do when they parse file names . */
2001-06-13 18:30:07 +00:00
base_name = lbasename ( s - > filename ) ;
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
if ( base_name ! = s - > filename
& & ! filename_seen ( base_name , 1 , & first )
# if HAVE_DOS_BASED_FILE_SYSTEM
& & strncasecmp ( base_name , text , text_len ) = = 0
# else
& & strncmp ( base_name , text , text_len ) = = 0
# endif
)
add_filename_to_list ( base_name , text , word ,
& list , & list_used , & list_alloced ) ;
}
}
ALL_PSYMTABS ( objfile , ps )
{
if ( not_interesting_fname ( ps - > filename ) )
continue ;
if ( ! ps - > readin )
{
if ( ! filename_seen ( ps - > filename , 1 , & first )
# if HAVE_DOS_BASED_FILE_SYSTEM
& & strncasecmp ( ps - > filename , text , text_len ) = = 0
# else
& & strncmp ( ps - > filename , text , text_len ) = = 0
# endif
)
{
/* This file matches for a completion; add it to the
current list of matches . */
add_filename_to_list ( ps - > filename , text , word ,
& list , & list_used , & list_alloced ) ;
}
else
{
2001-06-13 18:30:07 +00:00
base_name = lbasename ( ps - > filename ) ;
* completer.c (gdb_completer_loc_break_characters): New variable.
(line_completion_function): If we are completing on locations,
back up the start of word pointer past all characters which can
appear in a location spec.
(location_completer): New function.
* completer.h: Add prototype for location_completer.
* symtab.c (make_source_files_completion_list)
(add_filename_to_list, not_interesting_fname): New functions.
(filename_seen): New function, body extracted from
output_source_filename.
(output_source_filename): Call filename_seen to check if the file
was already printed.
(make_symbol_completion_list): If TEXT includes a
double-quoted string, return an empty list, not NULL.
(make_file_symbol_completion_list): New function, similar to
make_symbol_completion_list but with an additional argument
SRCFILE.
* symtab.h (make_file_symbol_completion_list)
(make_source_files_completion_list): Add prototypes.
* breakpoint.c (_initialize_breakpoint): Make location_completer
be the completion function for all commands which set breakpoints
and watchpoints.
(top-level): #include "completer.h".
* tracepoint.c (_initialize_tracepoint): Make location_completer
be the completion function for the "trace" command.
(top-level): #include "completer.h".
* printcmd.c (_initialize_printcmd): Make location_completer be
the completion function for the "print", "inspect", "call", and
"disassemble" commands.
(top-level): #include "completer.h".
* infcmd.c (_initialize_infcmd): Make location_completer be the
completion function for the "go", "jump", and "until" commands.
(top-level): #include "completer.h".
2001-06-11 16:05:25 +00:00
if ( base_name ! = ps - > filename
& & ! filename_seen ( base_name , 1 , & first )
# if HAVE_DOS_BASED_FILE_SYSTEM
& & strncasecmp ( base_name , text , text_len ) = = 0
# else
& & strncmp ( base_name , text , text_len ) = = 0
# endif
)
add_filename_to_list ( base_name , text , word ,
& list , & list_used , & list_alloced ) ;
}
}
}
return list ;
}
1999-04-16 01:35:26 +00:00
/* Determine if PC is in the prologue of a function. The prologue is the area
between the first instruction of a function , and the first executable line .
Returns 1 if PC * might * be in prologue , 0 if definately * not * in prologue .
If non - zero , func_start is where we think the prologue starts , possibly
by previous examination of symbol table information .
*/
int
2000-07-30 01:48:28 +00:00
in_prologue ( CORE_ADDR pc , CORE_ADDR func_start )
1999-04-16 01:35:26 +00:00
{
struct symtab_and_line sal ;
CORE_ADDR func_addr , func_end ;
2000-05-03 13:45:17 +00:00
/* We have several sources of information we can consult to figure
this out .
- Compilers usually emit line number info that marks the prologue
as its own " source line " . So the ending address of that " line "
is the end of the prologue . If available , this is the most
reliable method .
- The minimal symbols and partial symbols , which can usually tell
us the starting and ending addresses of a function .
- If we know the function ' s start address , we can call the
architecture - defined SKIP_PROLOGUE function to analyze the
instruction stream and guess where the prologue ends .
- Our ` func_start ' argument ; if non - zero , this is the caller ' s
best guess as to the function ' s entry point . At the time of
this writing , handle_inferior_event doesn ' t get this right , so
it should be our last resort . */
/* Consult the partial symbol table, to find which function
the PC is in . */
if ( ! find_pc_partial_function ( pc , NULL , & func_addr , & func_end ) )
{
CORE_ADDR prologue_end ;
1999-04-16 01:35:26 +00:00
2000-05-03 13:45:17 +00:00
/* We don't even have minsym information, so fall back to using
func_start , if given . */
if ( ! func_start )
return 1 ; /* We *might* be in a prologue. */
1999-04-16 01:35:26 +00:00
2000-05-03 13:45:17 +00:00
prologue_end = SKIP_PROLOGUE ( func_start ) ;
1999-04-16 01:35:26 +00:00
2000-05-03 13:45:17 +00:00
return func_start < = pc & & pc < prologue_end ;
}
1999-04-16 01:35:26 +00:00
2000-05-03 13:45:17 +00:00
/* If we have line number information for the function, that's
usually pretty reliable . */
sal = find_pc_line ( func_addr , 0 ) ;
1999-04-16 01:35:26 +00:00
2000-05-03 13:45:17 +00:00
/* Now sal describes the source line at the function's entry point,
which ( by convention ) is the prologue . The end of that " line " ,
sal . end , is the end of the prologue .
Note that , for functions whose source code is all on a single
line , the line number information doesn ' t always end up this way .
So we must verify that our purported end - of - prologue address is
* within * the function , not at its start or end . */
if ( sal . line = = 0
| | sal . end < = func_addr
| | func_end < = sal . end )
{
/* We don't have any good line number info, so use the minsym
information , together with the architecture - specific prologue
scanning code . */
CORE_ADDR prologue_end = SKIP_PROLOGUE ( func_addr ) ;
1999-04-16 01:35:26 +00:00
2000-05-03 13:45:17 +00:00
return func_addr < = pc & & pc < prologue_end ;
}
1999-04-16 01:35:26 +00:00
2000-05-03 13:45:17 +00:00
/* We have line number info, and it looks good. */
return func_addr < = pc & & pc < sal . end ;
1999-04-16 01:35:26 +00:00
}
/* Begin overload resolution functions */
2002-07-04 15:22:42 +00:00
static char *
remove_params ( const char * demangled_name )
{
const char * argp ;
char * new_name ;
int depth ;
if ( demangled_name = = NULL )
return NULL ;
/* First find the end of the arg list. */
argp = strrchr ( demangled_name , ' ) ' ) ;
if ( argp = = NULL )
return NULL ;
/* Back up to the beginning. */
depth = 1 ;
while ( argp - - > demangled_name )
{
if ( * argp = = ' ) ' )
depth + + ;
else if ( * argp = = ' ( ' )
{
depth - - ;
if ( depth = = 0 )
break ;
}
}
if ( depth ! = 0 )
internal_error ( __FILE__ , __LINE__ ,
" bad demangled name %s \n " , demangled_name ) ;
while ( argp [ - 1 ] = = ' ' & & argp > demangled_name )
argp - - ;
new_name = xmalloc ( argp - demangled_name + 1 ) ;
memcpy ( new_name , demangled_name , argp - demangled_name ) ;
new_name [ argp - demangled_name ] = ' \0 ' ;
return new_name ;
}
1999-04-16 01:35:26 +00:00
/* Helper routine for make_symbol_completion_list. */
static int sym_return_val_size ;
static int sym_return_val_index ;
static struct symbol * * sym_return_val ;
/* Test to see if the symbol specified by SYMNAME (which is already
1999-07-07 20:19:36 +00:00
demangled for C + + symbols ) matches SYM_TEXT in the first SYM_TEXT_LEN
characters . If so , add it to the current completion list . */
1999-04-16 01:35:26 +00:00
static void
2000-07-30 01:48:28 +00:00
overload_list_add_symbol ( struct symbol * sym , char * oload_name )
1999-04-16 01:35:26 +00:00
{
int newsize ;
int i ;
2002-07-04 15:22:42 +00:00
char * sym_name ;
/* If there is no type information, we can't do anything, so skip */
if ( SYMBOL_TYPE ( sym ) = = NULL )
return ;
/* skip any symbols that we've already considered. */
for ( i = 0 ; i < sym_return_val_index ; + + i )
if ( ! strcmp ( SYMBOL_NAME ( sym ) , SYMBOL_NAME ( sym_return_val [ i ] ) ) )
return ;
1999-04-16 01:35:26 +00:00
/* Get the demangled name without parameters */
2002-07-04 15:22:42 +00:00
sym_name = remove_params ( SYMBOL_DEMANGLED_NAME ( sym ) ) ;
1999-04-16 01:35:26 +00:00
if ( ! sym_name )
2002-07-04 15:22:42 +00:00
return ;
1999-04-16 01:35:26 +00:00
/* skip symbols that cannot match */
if ( strcmp ( sym_name , oload_name ) ! = 0 )
1999-10-19 02:47:02 +00:00
{
2000-12-15 01:01:51 +00:00
xfree ( sym_name ) ;
1999-10-19 02:47:02 +00:00
return ;
}
1999-04-16 01:35:26 +00:00
2002-07-04 15:22:42 +00:00
xfree ( sym_name ) ;
1999-04-16 01:35:26 +00:00
/* We have a match for an overload instance, so add SYM to the current list
* of overload instances */
if ( sym_return_val_index + 3 > sym_return_val_size )
{
newsize = ( sym_return_val_size * = 2 ) * sizeof ( struct symbol * ) ;
sym_return_val = ( struct symbol * * ) xrealloc ( ( char * ) sym_return_val , newsize ) ;
}
sym_return_val [ sym_return_val_index + + ] = sym ;
sym_return_val [ sym_return_val_index ] = NULL ;
}
/* Return a null-terminated list of pointers to function symbols that
* match name of the supplied symbol FSYM .
* This is used in finding all overloaded instances of a function name .
* This has been modified from make_symbol_completion_list . */
struct symbol * *
2000-07-30 01:48:28 +00:00
make_symbol_overload_list ( struct symbol * fsym )
1999-04-16 01:35:26 +00:00
{
register struct symbol * sym ;
register struct symtab * s ;
register struct partial_symtab * ps ;
register struct objfile * objfile ;
register struct block * b , * surrounding_static_block = 0 ;
1999-09-09 00:02:17 +00:00
register int i ;
1999-04-16 01:35:26 +00:00
/* The name we are completing on. */
char * oload_name = NULL ;
/* Length of name. */
int oload_name_len = 0 ;
2002-07-04 15:22:42 +00:00
/* Look for the symbol we are supposed to complete on. */
1999-04-16 01:35:26 +00:00
2002-07-04 15:22:42 +00:00
oload_name = remove_params ( SYMBOL_DEMANGLED_NAME ( fsym ) ) ;
1999-04-16 01:35:26 +00:00
if ( ! oload_name )
{
2002-07-04 15:22:42 +00:00
sym_return_val_size = 1 ;
sym_return_val = ( struct symbol * * ) xmalloc ( 2 * sizeof ( struct symbol * ) ) ;
sym_return_val [ 0 ] = fsym ;
sym_return_val [ 1 ] = NULL ;
return sym_return_val ;
1999-04-16 01:35:26 +00:00
}
oload_name_len = strlen ( oload_name ) ;
sym_return_val_size = 100 ;
sym_return_val_index = 0 ;
sym_return_val = ( struct symbol * * ) xmalloc ( ( sym_return_val_size + 1 ) * sizeof ( struct symbol * ) ) ;
sym_return_val [ 0 ] = NULL ;
/* Look through the partial symtabs for all symbols which begin
1999-10-19 02:47:02 +00:00
by matching OLOAD_NAME . Make sure we read that symbol table in . */
1999-04-16 01:35:26 +00:00
ALL_PSYMTABS ( objfile , ps )
1999-07-07 20:19:36 +00:00
{
1999-09-09 00:02:17 +00:00
struct partial_symbol * * psym ;
1999-07-07 20:19:36 +00:00
/* If the psymtab's been read in we'll get it when we search
through the blockvector . */
if ( ps - > readin )
continue ;
for ( psym = objfile - > global_psymbols . list + ps - > globals_offset ;
psym < ( objfile - > global_psymbols . list + ps - > globals_offset
+ ps - > n_global_syms ) ;
psym + + )
{
/* If interrupted, then quit. */
QUIT ;
1999-10-19 02:47:02 +00:00
/* This will cause the symbol table to be read if it has not yet been */
s = PSYMTAB_TO_SYMTAB ( ps ) ;
1999-07-07 20:19:36 +00:00
}
for ( psym = objfile - > static_psymbols . list + ps - > statics_offset ;
psym < ( objfile - > static_psymbols . list + ps - > statics_offset
+ ps - > n_static_syms ) ;
psym + + )
{
QUIT ;
1999-10-19 02:47:02 +00:00
/* This will cause the symbol table to be read if it has not yet been */
s = PSYMTAB_TO_SYMTAB ( ps ) ;
1999-07-07 20:19:36 +00:00
}
}
1999-04-16 01:35:26 +00:00
/* Search upwards from currently selected frame (so that we can
complete on local vars . */
gdb/ChangeLog:
* stack.c (get_selected_block): Add new argument `addr_in_block',
used to return the exact code address we used to select the block,
not just the block.
* blockframe.c (get_frame_block, get_current_block): Same.
* frame.h (get_frame_block, get_current_block,
get_selected_block): Update declarations.
* linespec.c, stack.c, blockframe.c, breakpoint.c, findvar.c,
linespec.c, varobj.c, printcmd.c, symtab.c: Callers changed.
gdb/mi/ChangeLog:
* mi-cmd-stack.c (list_args_or_locals): Pass new arg to
get_frame_block. (See entry in gdb/ChangeLog.)
2002-04-05 22:04:43 +00:00
for ( b = get_selected_block ( 0 ) ; b ! = NULL ; b = BLOCK_SUPERBLOCK ( b ) )
1999-04-16 01:35:26 +00:00
{
if ( ! BLOCK_SUPERBLOCK ( b ) )
{
1999-07-07 20:19:36 +00:00
surrounding_static_block = b ; /* For elimination of dups */
1999-04-16 01:35:26 +00:00
}
1999-07-07 20:19:36 +00:00
1999-04-16 01:35:26 +00:00
/* Also catch fields of types defined in this places which match our
1999-07-07 20:19:36 +00:00
text string . Only complete on types visible from current context . */
1999-04-16 01:35:26 +00:00
2001-10-12 23:51:30 +00:00
ALL_BLOCK_SYMBOLS ( b , i , sym )
1999-04-16 01:35:26 +00:00
{
overload_list_add_symbol ( sym , oload_name ) ;
}
}
/* Go through the symtabs and check the externs and statics for
symbols which match . */
ALL_SYMTABS ( objfile , s )
1999-07-07 20:19:36 +00:00
{
QUIT ;
b = BLOCKVECTOR_BLOCK ( BLOCKVECTOR ( s ) , GLOBAL_BLOCK ) ;
2001-10-12 23:51:30 +00:00
ALL_BLOCK_SYMBOLS ( b , i , sym )
1999-07-07 20:19:36 +00:00
{
overload_list_add_symbol ( sym , oload_name ) ;
}
}
1999-04-16 01:35:26 +00:00
ALL_SYMTABS ( objfile , s )
1999-07-07 20:19:36 +00:00
{
QUIT ;
b = BLOCKVECTOR_BLOCK ( BLOCKVECTOR ( s ) , STATIC_BLOCK ) ;
/* Don't do this block twice. */
if ( b = = surrounding_static_block )
continue ;
2001-10-12 23:51:30 +00:00
ALL_BLOCK_SYMBOLS ( b , i , sym )
1999-07-07 20:19:36 +00:00
{
overload_list_add_symbol ( sym , oload_name ) ;
}
}
1999-04-16 01:35:26 +00:00
2000-12-15 01:01:51 +00:00
xfree ( oload_name ) ;
1999-04-16 01:35:26 +00:00
return ( sym_return_val ) ;
}
/* End of overload resolution functions */
2000-11-10 23:02:56 +00:00
struct symtabs_and_lines
decode_line_spec ( char * string , int funfirstline )
{
struct symtabs_and_lines sals ;
2002-09-20 14:58:59 +00:00
struct symtab_and_line cursal ;
2000-11-10 23:02:56 +00:00
if ( string = = 0 )
error ( " Empty line specification. " ) ;
2002-09-20 14:58:59 +00:00
/* We use whatever is set as the current source line. We do not try
and get a default or it will recursively call us ! */
cursal = get_current_source_symtab_and_line ( ) ;
2000-11-10 23:02:56 +00:00
sals = decode_line_1 ( & string , funfirstline ,
2002-09-20 14:58:59 +00:00
cursal . symtab , cursal . line ,
2000-11-10 23:02:56 +00:00
( char * * * ) NULL ) ;
2002-09-20 14:58:59 +00:00
2000-11-10 23:02:56 +00:00
if ( * string )
error ( " Junk at end of line specification: %s " , string ) ;
return sals ;
}
1999-07-07 20:19:36 +00:00
2001-07-07 17:19:50 +00:00
/* Track MAIN */
static char * name_of_main ;
void
set_main_name ( const char * name )
{
if ( name_of_main ! = NULL )
{
xfree ( name_of_main ) ;
name_of_main = NULL ;
}
if ( name ! = NULL )
{
name_of_main = xstrdup ( name ) ;
}
}
char *
main_name ( void )
{
if ( name_of_main ! = NULL )
return name_of_main ;
else
return " main " ;
}
1999-04-16 01:35:26 +00:00
void
2000-07-30 01:48:28 +00:00
_initialize_symtab ( void )
1999-04-16 01:35:26 +00:00
{
add_info ( " variables " , variables_info ,
1999-07-07 20:19:36 +00:00
" All global and static variable names, or those matching REGEXP. " ) ;
1999-04-16 01:35:26 +00:00
if ( dbx_commands )
1999-07-07 20:19:36 +00:00
add_com ( " whereis " , class_info , variables_info ,
" All global and static variable names, or those matching REGEXP. " ) ;
1999-04-16 01:35:26 +00:00
add_info ( " functions " , functions_info ,
" All function names, or those matching REGEXP. " ) ;
2000-06-05 20:49:53 +00:00
1999-04-16 01:35:26 +00:00
/* FIXME: This command has at least the following problems:
1. It prints builtin types ( in a very strange and confusing fashion ) .
2. It doesn ' t print right , e . g . with
1999-07-07 20:19:36 +00:00
typedef struct foo * FOO
type_print prints " FOO " when we want to make it ( in this situation )
print " struct foo * " .
1999-04-16 01:35:26 +00:00
I also think " ptype " or " whatis " is more likely to be useful ( but if
there is much disagreement " info types " can be fixed ) . */
add_info ( " types " , types_info ,
" All type names, or those matching REGEXP. " ) ;
add_info ( " sources " , sources_info ,
" Source files in the program. " ) ;
add_com ( " rbreak " , class_breakpoint , rbreak_command ,
1999-07-07 20:19:36 +00:00
" Set a breakpoint for all functions matching REGEXP. " ) ;
1999-04-16 01:35:26 +00:00
if ( xdb_commands )
{
add_com ( " lf " , class_info , sources_info , " Source files in the program " ) ;
add_com ( " lg " , class_info , variables_info ,
1999-07-07 20:19:36 +00:00
" All global and static variable names, or those matching REGEXP. " ) ;
1999-04-16 01:35:26 +00:00
}
/* Initialize the one built-in type that isn't language dependent... */
builtin_type_error = init_type ( TYPE_CODE_ERROR , 0 , 0 ,
" <unknown type> " , ( struct objfile * ) NULL ) ;
}