mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-26 12:25:31 +00:00
* ada-tasks.c: Rename build_task_list to ada_build_task_list, and
make it non-static. * ada-lang.h (task_control_block): declaration moved from ada-task.c to ada-lang.h; this is needed to be able to implement the kill command in multi-task mode. (task_ptid): Ditto. (task_entry): Ditto. (task_list): Ditto. (ada_build_task_list): Ditto. * ada-lang.c: Conditionalize routines and data structures related to breakpoints, exceptions, completion, and symbol caching on GNAT_GDB, since these are not yet used in the submitted public sources. (ada_main_name): Editorial: Move definition out of exception-related code.
This commit is contained in:
parent
08fd625c2e
commit
96d887e830
@ -1,3 +1,21 @@
|
||||
2004-06-16 Paul N. Hilfinger <Hilfinger@gnat.com>
|
||||
|
||||
* ada-tasks.c: Rename build_task_list to ada_build_task_list, and
|
||||
make it non-static.
|
||||
* ada-lang.h (task_control_block): declaration moved from ada-task.c
|
||||
to ada-lang.h; this is needed to be able to implement the kill command
|
||||
in multi-task mode.
|
||||
(task_ptid): Ditto.
|
||||
(task_entry): Ditto.
|
||||
(task_list): Ditto.
|
||||
(ada_build_task_list): Ditto.
|
||||
|
||||
* ada-lang.c: Conditionalize routines and data structures related
|
||||
to breakpoints, exceptions, completion, and symbol caching on
|
||||
GNAT_GDB, since these are not yet used in the submitted public sources.
|
||||
(ada_main_name): Editorial: Move definition out of exception-related
|
||||
code.
|
||||
|
||||
2004-06-15 Andrew Cagney <cagney@gnu.org>
|
||||
|
||||
* mips-tdep.c (non_heuristic_proc_desc): Delete call to
|
||||
|
707
gdb/ada-lang.c
707
gdb/ada-lang.c
@ -18,6 +18,19 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
/* Sections of code marked
|
||||
|
||||
#ifdef GNAT_GDB
|
||||
...
|
||||
#endif
|
||||
|
||||
indicate sections that are used in sources distributed by
|
||||
ACT, Inc., but not yet integrated into the public tree (where
|
||||
GNAT_GDB is not defined). They are retained here nevertheless
|
||||
to minimize the problems of maintaining different versions
|
||||
of the source and to make the full source available. */
|
||||
|
||||
#include "defs.h"
|
||||
#include <stdio.h>
|
||||
#include "gdb_string.h"
|
||||
@ -62,6 +75,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2)
|
||||
#endif
|
||||
|
||||
#ifdef GNAT_GDB
|
||||
/* A structure that contains a vector of strings.
|
||||
The main purpose of this type is to group the vector and its
|
||||
associated parameters in one structure. This makes it easier
|
||||
@ -76,6 +90,7 @@ struct string_vector
|
||||
|
||||
static struct string_vector xnew_string_vector (int initial_size);
|
||||
static void string_vector_append (struct string_vector *sv, char *str);
|
||||
#endif /* GNAT_GDB */
|
||||
|
||||
static const char *ada_unqualified_name (const char *decoded_name);
|
||||
static char *add_angle_brackets (const char *str);
|
||||
@ -332,6 +347,8 @@ static struct obstack symbol_list_obstack;
|
||||
|
||||
/* Utilities */
|
||||
|
||||
#ifdef GNAT_GDB
|
||||
|
||||
/* Create a new empty string_vector struct with an initial size of
|
||||
INITIAL_SIZE. */
|
||||
|
||||
@ -392,6 +409,8 @@ add_angle_brackets (const char *str)
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* GNAT_GDB */
|
||||
|
||||
static char *
|
||||
ada_get_gdb_completer_word_break_characters (void)
|
||||
{
|
||||
@ -705,6 +724,37 @@ ada_update_initial_language (enum language lang,
|
||||
|
||||
return lang;
|
||||
}
|
||||
|
||||
/* If the main procedure is written in Ada, then return its name.
|
||||
The result is good until the next call. Return NULL if the main
|
||||
procedure doesn't appear to be in Ada. */
|
||||
|
||||
char *
|
||||
ada_main_name (void)
|
||||
{
|
||||
struct minimal_symbol *msym;
|
||||
CORE_ADDR main_program_name_addr;
|
||||
static char main_program_name[1024];
|
||||
/* For Ada, the name of the main procedure is stored in a specific
|
||||
string constant, generated by the binder. Look for that symbol,
|
||||
extract its address, and then read that string. If we didn't find
|
||||
that string, then most probably the main procedure is not written
|
||||
in Ada. */
|
||||
msym = lookup_minimal_symbol (ADA_MAIN_PROGRAM_SYMBOL_NAME, NULL, NULL);
|
||||
|
||||
if (msym != NULL)
|
||||
{
|
||||
main_program_name_addr = SYMBOL_VALUE_ADDRESS (msym);
|
||||
if (main_program_name_addr == 0)
|
||||
error ("Invalid address for Ada main program name.");
|
||||
|
||||
extract_string (main_program_name_addr, main_program_name);
|
||||
return main_program_name;
|
||||
}
|
||||
|
||||
/* The main procedure doesn't seem to be in Ada. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Symbols */
|
||||
|
||||
@ -3597,6 +3647,13 @@ ada_convert_actuals (struct value *func, int nargs, struct value *args[],
|
||||
|
||||
/* Experimental Symbol Cache Module */
|
||||
|
||||
/* This module may well have been OBE, due to improvements in the
|
||||
symbol-table module. So until proven otherwise, it is disabled in
|
||||
the submitted public code, and may be removed from all sources
|
||||
in the future. */
|
||||
|
||||
#ifdef GNAT_GDB
|
||||
|
||||
/* This section implements a simple, fixed-sized hash table for those
|
||||
Ada-mode symbols that get looked up in the course of executing the user's
|
||||
commands. The size is fixed on the grounds that there are not
|
||||
@ -3686,6 +3743,22 @@ cache_symbol (const char *name, domain_enum namespace, struct symbol *sym,
|
||||
e->symtab = symtab;
|
||||
e->block = block;
|
||||
}
|
||||
|
||||
#else
|
||||
static int
|
||||
lookup_cached_symbol (const char *name, domain_enum namespace,
|
||||
struct symbol **sym, struct block **block,
|
||||
struct symtab **symtab)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cache_symbol (const char *name, domain_enum namespace, struct symbol *sym,
|
||||
struct block *block, struct symtab *symtab)
|
||||
{
|
||||
}
|
||||
#endif /* GNAT_GDB */
|
||||
|
||||
/* Symbol Lookup */
|
||||
|
||||
@ -3841,293 +3914,6 @@ defns_collected (struct obstack *obstackp, int finish)
|
||||
return (struct ada_symbol_info *) obstack_base (obstackp);
|
||||
}
|
||||
|
||||
/* If SYM_NAME is a completion candidate for TEXT, return this symbol
|
||||
name in a form that's appropriate for the completion. The result
|
||||
does not need to be deallocated, but is only good until the next call.
|
||||
|
||||
TEXT_LEN is equal to the length of TEXT.
|
||||
Perform a wild match if WILD_MATCH is set.
|
||||
ENCODED should be set if TEXT represents the start of a symbol name
|
||||
in its encoded form. */
|
||||
|
||||
static const char *
|
||||
symbol_completion_match (const char *sym_name,
|
||||
const char *text, int text_len,
|
||||
int wild_match, int encoded)
|
||||
{
|
||||
char *result;
|
||||
const int verbatim_match = (text[0] == '<');
|
||||
int match = 0;
|
||||
|
||||
if (verbatim_match)
|
||||
{
|
||||
/* Strip the leading angle bracket. */
|
||||
text = text + 1;
|
||||
text_len--;
|
||||
}
|
||||
|
||||
/* First, test against the fully qualified name of the symbol. */
|
||||
|
||||
if (strncmp (sym_name, text, text_len) == 0)
|
||||
match = 1;
|
||||
|
||||
if (match && !encoded)
|
||||
{
|
||||
/* One needed check before declaring a positive match is to verify
|
||||
that iff we are doing a verbatim match, the decoded version
|
||||
of the symbol name starts with '<'. Otherwise, this symbol name
|
||||
is not a suitable completion. */
|
||||
const char *sym_name_copy = sym_name;
|
||||
int has_angle_bracket;
|
||||
|
||||
sym_name = ada_decode (sym_name);
|
||||
has_angle_bracket = (sym_name [0] == '<');
|
||||
match = (has_angle_bracket == verbatim_match);
|
||||
sym_name = sym_name_copy;
|
||||
}
|
||||
|
||||
if (match && !verbatim_match)
|
||||
{
|
||||
/* When doing non-verbatim match, another check that needs to
|
||||
be done is to verify that the potentially matching symbol name
|
||||
does not include capital letters, because the ada-mode would
|
||||
not be able to understand these symbol names without the
|
||||
angle bracket notation. */
|
||||
const char *tmp;
|
||||
|
||||
for (tmp = sym_name; *tmp != '\0' && !isupper (*tmp); tmp++);
|
||||
if (*tmp != '\0')
|
||||
match = 0;
|
||||
}
|
||||
|
||||
/* Second: Try wild matching... */
|
||||
|
||||
if (!match && wild_match)
|
||||
{
|
||||
/* Since we are doing wild matching, this means that TEXT
|
||||
may represent an unqualified symbol name. We therefore must
|
||||
also compare TEXT against the unqualified name of the symbol. */
|
||||
sym_name = ada_unqualified_name (ada_decode (sym_name));
|
||||
|
||||
if (strncmp (sym_name, text, text_len) == 0)
|
||||
match = 1;
|
||||
}
|
||||
|
||||
/* Finally: If we found a mach, prepare the result to return. */
|
||||
|
||||
if (!match)
|
||||
return NULL;
|
||||
|
||||
if (verbatim_match)
|
||||
sym_name = add_angle_brackets (sym_name);
|
||||
|
||||
if (!encoded)
|
||||
sym_name = ada_decode (sym_name);
|
||||
|
||||
return sym_name;
|
||||
}
|
||||
|
||||
/* A companion function to ada_make_symbol_completion_list().
|
||||
Check if SYM_NAME represents a symbol which name would be suitable
|
||||
to complete TEXT (TEXT_LEN is the length of TEXT), in which case
|
||||
it is appended at the end of the given string vector SV.
|
||||
|
||||
ORIG_TEXT is the string original string from the user command
|
||||
that needs to be completed. WORD is the entire command on which
|
||||
completion should be performed. These two parameters are used to
|
||||
determine which part of the symbol name should be added to the
|
||||
completion vector.
|
||||
if WILD_MATCH is set, then wild matching is performed.
|
||||
ENCODED should be set if TEXT represents a symbol name in its
|
||||
encoded formed (in which case the completion should also be
|
||||
encoded). */
|
||||
|
||||
static void
|
||||
symbol_completion_add (struct string_vector *sv,
|
||||
const char *sym_name,
|
||||
const char *text, int text_len,
|
||||
const char *orig_text, const char *word,
|
||||
int wild_match, int encoded)
|
||||
{
|
||||
const char *match = symbol_completion_match (sym_name, text, text_len,
|
||||
wild_match, encoded);
|
||||
char *completion;
|
||||
|
||||
if (match == NULL)
|
||||
return;
|
||||
|
||||
/* We found a match, so add the appropriate completion to the given
|
||||
string vector. */
|
||||
|
||||
if (word == orig_text)
|
||||
{
|
||||
completion = xmalloc (strlen (match) + 5);
|
||||
strcpy (completion, match);
|
||||
}
|
||||
else if (word > orig_text)
|
||||
{
|
||||
/* Return some portion of sym_name. */
|
||||
completion = xmalloc (strlen (match) + 5);
|
||||
strcpy (completion, match + (word - orig_text));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return some of ORIG_TEXT plus sym_name. */
|
||||
completion = xmalloc (strlen (match) + (orig_text - word) + 5);
|
||||
strncpy (completion, word, orig_text - word);
|
||||
completion[orig_text - word] = '\0';
|
||||
strcat (completion, match);
|
||||
}
|
||||
|
||||
string_vector_append (sv, completion);
|
||||
}
|
||||
|
||||
/* Return a list of possible symbol names completing TEXT0. The list
|
||||
is NULL terminated. WORD is the entire command on which completion
|
||||
is made. */
|
||||
|
||||
char **
|
||||
ada_make_symbol_completion_list (const char *text0, const char *word)
|
||||
{
|
||||
/* Note: This function is almost a copy of make_symbol_completion_list(),
|
||||
except it has been adapted for Ada. It is somewhat of a shame to
|
||||
duplicate so much code, but we don't really have the infrastructure
|
||||
yet to develop a language-aware version of he symbol completer... */
|
||||
char *text;
|
||||
int text_len;
|
||||
int wild_match;
|
||||
int encoded;
|
||||
struct string_vector result = xnew_string_vector (128);
|
||||
struct symbol *sym;
|
||||
struct symtab *s;
|
||||
struct partial_symtab *ps;
|
||||
struct minimal_symbol *msymbol;
|
||||
struct objfile *objfile;
|
||||
struct block *b, *surrounding_static_block = 0;
|
||||
int i;
|
||||
struct dict_iterator iter;
|
||||
|
||||
if (text0[0] == '<')
|
||||
{
|
||||
text = xstrdup (text0);
|
||||
make_cleanup (xfree, text);
|
||||
text_len = strlen (text);
|
||||
wild_match = 0;
|
||||
encoded = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = xstrdup (ada_encode (text0));
|
||||
make_cleanup (xfree, text);
|
||||
text_len = strlen (text);
|
||||
for (i = 0; i < text_len; i++)
|
||||
text[i] = tolower (text[i]);
|
||||
|
||||
/* FIXME: brobecker/2003-09-17: When we get rid of ADA_RETAIN_DOTS,
|
||||
we can restrict the wild_match check to searching "__" only. */
|
||||
wild_match = (strstr (text0, "__") == NULL
|
||||
&& strchr (text0, '.') == NULL);
|
||||
encoded = (strstr (text0, "__") != NULL);
|
||||
}
|
||||
|
||||
/* First, look at the partial symtab symbols. */
|
||||
ALL_PSYMTABS (objfile, ps)
|
||||
{
|
||||
struct partial_symbol **psym;
|
||||
|
||||
/* 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++)
|
||||
{
|
||||
QUIT;
|
||||
symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (*psym),
|
||||
text, text_len, text0, word,
|
||||
wild_match, encoded);
|
||||
}
|
||||
|
||||
for (psym = objfile->static_psymbols.list + ps->statics_offset;
|
||||
psym < (objfile->static_psymbols.list + ps->statics_offset
|
||||
+ ps->n_static_syms);
|
||||
psym++)
|
||||
{
|
||||
QUIT;
|
||||
symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (*psym),
|
||||
text, text_len, text0, word,
|
||||
wild_match, encoded);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
QUIT;
|
||||
symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (msymbol),
|
||||
text, text_len, text0, word,
|
||||
wild_match, encoded);
|
||||
}
|
||||
|
||||
/* Search upwards from currently selected frame (so that we can
|
||||
complete on local vars. */
|
||||
|
||||
for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
|
||||
{
|
||||
if (!BLOCK_SUPERBLOCK (b))
|
||||
surrounding_static_block = b; /* For elmin of dups */
|
||||
|
||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
||||
{
|
||||
symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
|
||||
text, text_len, text0, word,
|
||||
wild_match, encoded);
|
||||
}
|
||||
}
|
||||
|
||||
/* Go through the symtabs and check the externs and statics for
|
||||
symbols which match. */
|
||||
|
||||
ALL_SYMTABS (objfile, s)
|
||||
{
|
||||
QUIT;
|
||||
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
|
||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
||||
{
|
||||
symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
|
||||
text, text_len, text0, word,
|
||||
wild_match, encoded);
|
||||
}
|
||||
}
|
||||
|
||||
ALL_SYMTABS (objfile, s)
|
||||
{
|
||||
QUIT;
|
||||
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
|
||||
/* Don't do this block twice. */
|
||||
if (b == surrounding_static_block)
|
||||
continue;
|
||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
||||
{
|
||||
symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
|
||||
text, text_len, text0, word,
|
||||
wild_match, encoded);
|
||||
}
|
||||
}
|
||||
|
||||
/* Append the closing NULL entry. */
|
||||
string_vector_append (&result, NULL);
|
||||
|
||||
return (result.array);
|
||||
}
|
||||
|
||||
/* Look, in partial_symtab PST, for symbol NAME in given namespace.
|
||||
Check the global symbols if GLOBAL, the static symbols if not.
|
||||
Do wild-card match if WILD. */
|
||||
@ -5339,6 +5125,300 @@ ada_add_block_symbols (struct obstack *obstackp,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GNAT_GDB
|
||||
|
||||
/* Symbol Completion */
|
||||
|
||||
/* If SYM_NAME is a completion candidate for TEXT, return this symbol
|
||||
name in a form that's appropriate for the completion. The result
|
||||
does not need to be deallocated, but is only good until the next call.
|
||||
|
||||
TEXT_LEN is equal to the length of TEXT.
|
||||
Perform a wild match if WILD_MATCH is set.
|
||||
ENCODED should be set if TEXT represents the start of a symbol name
|
||||
in its encoded form. */
|
||||
|
||||
static const char *
|
||||
symbol_completion_match (const char *sym_name,
|
||||
const char *text, int text_len,
|
||||
int wild_match, int encoded)
|
||||
{
|
||||
char *result;
|
||||
const int verbatim_match = (text[0] == '<');
|
||||
int match = 0;
|
||||
|
||||
if (verbatim_match)
|
||||
{
|
||||
/* Strip the leading angle bracket. */
|
||||
text = text + 1;
|
||||
text_len--;
|
||||
}
|
||||
|
||||
/* First, test against the fully qualified name of the symbol. */
|
||||
|
||||
if (strncmp (sym_name, text, text_len) == 0)
|
||||
match = 1;
|
||||
|
||||
if (match && !encoded)
|
||||
{
|
||||
/* One needed check before declaring a positive match is to verify
|
||||
that iff we are doing a verbatim match, the decoded version
|
||||
of the symbol name starts with '<'. Otherwise, this symbol name
|
||||
is not a suitable completion. */
|
||||
const char *sym_name_copy = sym_name;
|
||||
int has_angle_bracket;
|
||||
|
||||
sym_name = ada_decode (sym_name);
|
||||
has_angle_bracket = (sym_name [0] == '<');
|
||||
match = (has_angle_bracket == verbatim_match);
|
||||
sym_name = sym_name_copy;
|
||||
}
|
||||
|
||||
if (match && !verbatim_match)
|
||||
{
|
||||
/* When doing non-verbatim match, another check that needs to
|
||||
be done is to verify that the potentially matching symbol name
|
||||
does not include capital letters, because the ada-mode would
|
||||
not be able to understand these symbol names without the
|
||||
angle bracket notation. */
|
||||
const char *tmp;
|
||||
|
||||
for (tmp = sym_name; *tmp != '\0' && !isupper (*tmp); tmp++);
|
||||
if (*tmp != '\0')
|
||||
match = 0;
|
||||
}
|
||||
|
||||
/* Second: Try wild matching... */
|
||||
|
||||
if (!match && wild_match)
|
||||
{
|
||||
/* Since we are doing wild matching, this means that TEXT
|
||||
may represent an unqualified symbol name. We therefore must
|
||||
also compare TEXT against the unqualified name of the symbol. */
|
||||
sym_name = ada_unqualified_name (ada_decode (sym_name));
|
||||
|
||||
if (strncmp (sym_name, text, text_len) == 0)
|
||||
match = 1;
|
||||
}
|
||||
|
||||
/* Finally: If we found a mach, prepare the result to return. */
|
||||
|
||||
if (!match)
|
||||
return NULL;
|
||||
|
||||
if (verbatim_match)
|
||||
sym_name = add_angle_brackets (sym_name);
|
||||
|
||||
if (!encoded)
|
||||
sym_name = ada_decode (sym_name);
|
||||
|
||||
return sym_name;
|
||||
}
|
||||
|
||||
/* A companion function to ada_make_symbol_completion_list().
|
||||
Check if SYM_NAME represents a symbol which name would be suitable
|
||||
to complete TEXT (TEXT_LEN is the length of TEXT), in which case
|
||||
it is appended at the end of the given string vector SV.
|
||||
|
||||
ORIG_TEXT is the string original string from the user command
|
||||
that needs to be completed. WORD is the entire command on which
|
||||
completion should be performed. These two parameters are used to
|
||||
determine which part of the symbol name should be added to the
|
||||
completion vector.
|
||||
if WILD_MATCH is set, then wild matching is performed.
|
||||
ENCODED should be set if TEXT represents a symbol name in its
|
||||
encoded formed (in which case the completion should also be
|
||||
encoded). */
|
||||
|
||||
static void
|
||||
symbol_completion_add (struct string_vector *sv,
|
||||
const char *sym_name,
|
||||
const char *text, int text_len,
|
||||
const char *orig_text, const char *word,
|
||||
int wild_match, int encoded)
|
||||
{
|
||||
const char *match = symbol_completion_match (sym_name, text, text_len,
|
||||
wild_match, encoded);
|
||||
char *completion;
|
||||
|
||||
if (match == NULL)
|
||||
return;
|
||||
|
||||
/* We found a match, so add the appropriate completion to the given
|
||||
string vector. */
|
||||
|
||||
if (word == orig_text)
|
||||
{
|
||||
completion = xmalloc (strlen (match) + 5);
|
||||
strcpy (completion, match);
|
||||
}
|
||||
else if (word > orig_text)
|
||||
{
|
||||
/* Return some portion of sym_name. */
|
||||
completion = xmalloc (strlen (match) + 5);
|
||||
strcpy (completion, match + (word - orig_text));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return some of ORIG_TEXT plus sym_name. */
|
||||
completion = xmalloc (strlen (match) + (orig_text - word) + 5);
|
||||
strncpy (completion, word, orig_text - word);
|
||||
completion[orig_text - word] = '\0';
|
||||
strcat (completion, match);
|
||||
}
|
||||
|
||||
string_vector_append (sv, completion);
|
||||
}
|
||||
|
||||
/* Return a list of possible symbol names completing TEXT0. The list
|
||||
is NULL terminated. WORD is the entire command on which completion
|
||||
is made. */
|
||||
|
||||
char **
|
||||
ada_make_symbol_completion_list (const char *text0, const char *word)
|
||||
{
|
||||
/* Note: This function is almost a copy of make_symbol_completion_list(),
|
||||
except it has been adapted for Ada. It is somewhat of a shame to
|
||||
duplicate so much code, but we don't really have the infrastructure
|
||||
yet to develop a language-aware version of he symbol completer... */
|
||||
char *text;
|
||||
int text_len;
|
||||
int wild_match;
|
||||
int encoded;
|
||||
struct string_vector result = xnew_string_vector (128);
|
||||
struct symbol *sym;
|
||||
struct symtab *s;
|
||||
struct partial_symtab *ps;
|
||||
struct minimal_symbol *msymbol;
|
||||
struct objfile *objfile;
|
||||
struct block *b, *surrounding_static_block = 0;
|
||||
int i;
|
||||
struct dict_iterator iter;
|
||||
|
||||
if (text0[0] == '<')
|
||||
{
|
||||
text = xstrdup (text0);
|
||||
make_cleanup (xfree, text);
|
||||
text_len = strlen (text);
|
||||
wild_match = 0;
|
||||
encoded = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = xstrdup (ada_encode (text0));
|
||||
make_cleanup (xfree, text);
|
||||
text_len = strlen (text);
|
||||
for (i = 0; i < text_len; i++)
|
||||
text[i] = tolower (text[i]);
|
||||
|
||||
/* FIXME: brobecker/2003-09-17: When we get rid of ADA_RETAIN_DOTS,
|
||||
we can restrict the wild_match check to searching "__" only. */
|
||||
wild_match = (strstr (text0, "__") == NULL
|
||||
&& strchr (text0, '.') == NULL);
|
||||
encoded = (strstr (text0, "__") != NULL);
|
||||
}
|
||||
|
||||
/* First, look at the partial symtab symbols. */
|
||||
ALL_PSYMTABS (objfile, ps)
|
||||
{
|
||||
struct partial_symbol **psym;
|
||||
|
||||
/* 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++)
|
||||
{
|
||||
QUIT;
|
||||
symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (*psym),
|
||||
text, text_len, text0, word,
|
||||
wild_match, encoded);
|
||||
}
|
||||
|
||||
for (psym = objfile->static_psymbols.list + ps->statics_offset;
|
||||
psym < (objfile->static_psymbols.list + ps->statics_offset
|
||||
+ ps->n_static_syms);
|
||||
psym++)
|
||||
{
|
||||
QUIT;
|
||||
symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (*psym),
|
||||
text, text_len, text0, word,
|
||||
wild_match, encoded);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
QUIT;
|
||||
symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (msymbol),
|
||||
text, text_len, text0, word,
|
||||
wild_match, encoded);
|
||||
}
|
||||
|
||||
/* Search upwards from currently selected frame (so that we can
|
||||
complete on local vars. */
|
||||
|
||||
for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
|
||||
{
|
||||
if (!BLOCK_SUPERBLOCK (b))
|
||||
surrounding_static_block = b; /* For elmin of dups */
|
||||
|
||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
||||
{
|
||||
symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
|
||||
text, text_len, text0, word,
|
||||
wild_match, encoded);
|
||||
}
|
||||
}
|
||||
|
||||
/* Go through the symtabs and check the externs and statics for
|
||||
symbols which match. */
|
||||
|
||||
ALL_SYMTABS (objfile, s)
|
||||
{
|
||||
QUIT;
|
||||
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
|
||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
||||
{
|
||||
symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
|
||||
text, text_len, text0, word,
|
||||
wild_match, encoded);
|
||||
}
|
||||
}
|
||||
|
||||
ALL_SYMTABS (objfile, s)
|
||||
{
|
||||
QUIT;
|
||||
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
|
||||
/* Don't do this block twice. */
|
||||
if (b == surrounding_static_block)
|
||||
continue;
|
||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
||||
{
|
||||
symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
|
||||
text, text_len, text0, word,
|
||||
wild_match, encoded);
|
||||
}
|
||||
}
|
||||
|
||||
/* Append the closing NULL entry. */
|
||||
string_vector_append (&result, NULL);
|
||||
|
||||
return (result.array);
|
||||
}
|
||||
|
||||
#endif /* GNAT_GDB */
|
||||
|
||||
#ifdef GNAT_GDB
|
||||
/* Breakpoint-related */
|
||||
|
||||
/* Import message from symtab.c. */
|
||||
@ -6041,37 +6121,6 @@ extended_canonical_line_spec (struct symtab_and_line sal, const char *name)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* If the main procedure is written in Ada, then return its name.
|
||||
The result is good until the next call. Return NULL if the main
|
||||
procedure doesn't appear to be in Ada. */
|
||||
|
||||
char *
|
||||
ada_main_name (void)
|
||||
{
|
||||
struct minimal_symbol *msym;
|
||||
CORE_ADDR main_program_name_addr;
|
||||
static char main_program_name[1024];
|
||||
/* For Ada, the name of the main procedure is stored in a specific
|
||||
string constant, generated by the binder. Look for that symbol,
|
||||
extract its address, and then read that string. If we didn't find
|
||||
that string, then most probably the main procedure is not written
|
||||
in Ada. */
|
||||
msym = lookup_minimal_symbol (ADA_MAIN_PROGRAM_SYMBOL_NAME, NULL, NULL);
|
||||
|
||||
if (msym != NULL)
|
||||
{
|
||||
main_program_name_addr = SYMBOL_VALUE_ADDRESS (msym);
|
||||
if (main_program_name_addr == 0)
|
||||
error ("Invalid address for Ada main program name.");
|
||||
|
||||
extract_string (main_program_name_addr, main_program_name);
|
||||
return main_program_name;
|
||||
}
|
||||
|
||||
/* The main procedure doesn't seem to be in Ada. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return type of Ada breakpoint associated with bp_stat:
|
||||
0 if not an Ada-specific breakpoint, 1 for break on specific exception,
|
||||
2 for break on unhandled exception, 3 for assert. */
|
||||
@ -6079,12 +6128,8 @@ ada_main_name (void)
|
||||
static int
|
||||
ada_exception_breakpoint_type (bpstat bs)
|
||||
{
|
||||
#ifdef GNAT_GDB
|
||||
return ((! bs || ! bs->breakpoint_at) ? 0
|
||||
: bs->breakpoint_at->break_on_exception);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* True iff FRAME is very likely to be that of a function that is
|
||||
@ -6285,7 +6330,6 @@ exception_name_from_cond (const char *condition)
|
||||
int
|
||||
ada_print_exception_breakpoint_nontask (struct breakpoint *b)
|
||||
{
|
||||
#ifdef GNAT_GDB
|
||||
if (b->break_on_exception == 1)
|
||||
{
|
||||
if (b->cond_string) /* the breakpoint is on a specific exception. */
|
||||
@ -6314,9 +6358,6 @@ ada_print_exception_breakpoint_nontask (struct breakpoint *b)
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Print task identifier for breakpoint B, if it is an Ada-specific
|
||||
@ -6325,13 +6366,11 @@ ada_print_exception_breakpoint_nontask (struct breakpoint *b)
|
||||
void
|
||||
ada_print_exception_breakpoint_task (struct breakpoint *b)
|
||||
{
|
||||
#ifdef GNAT_GDB
|
||||
if (b->task != 0)
|
||||
{
|
||||
ui_out_text (uiout, " task ");
|
||||
ui_out_field_int (uiout, "task", b->task);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
@ -6476,8 +6515,8 @@ ada_breakpoint_rewrite (char *arg, int *break_on_exceptionp)
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Field Access */
|
||||
|
||||
/* True if field number FIELD_NUM in struct or union type TYPE is supposed
|
||||
@ -10098,7 +10137,7 @@ const struct language_defn ada_language_defn = {
|
||||
#ifdef GNAT_GDB
|
||||
ada_lookup_symbol,
|
||||
ada_lookup_minimal_symbol,
|
||||
#endif
|
||||
#endif /* GNAT_GDB */
|
||||
&ada_exp_descriptor,
|
||||
parse,
|
||||
ada_error,
|
||||
@ -10134,7 +10173,7 @@ const struct language_defn ada_language_defn = {
|
||||
#ifdef GNAT_GDB
|
||||
ada_translate_error_message, /* Substitute Ada-specific terminology
|
||||
in errors and warnings. */
|
||||
#endif
|
||||
#endif /* GNAT_GDB */
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
@ -10186,17 +10225,17 @@ _initialize_ada_language (void)
|
||||
deprecated_register_gdbarch_swap (NULL, 0, build_ada_types);
|
||||
add_language (&ada_language_defn);
|
||||
|
||||
varsize_limit = 65536;
|
||||
#ifdef GNAT_GDB
|
||||
add_show_from_set
|
||||
(add_set_cmd ("varsize-limit", class_support, var_uinteger,
|
||||
(char *) &varsize_limit,
|
||||
"Set maximum bytes in dynamic-sized object.",
|
||||
&setlist), &showlist);
|
||||
#endif
|
||||
varsize_limit = 65536;
|
||||
obstack_init (&cache_space);
|
||||
#endif /* GNAT_GDB */
|
||||
|
||||
obstack_init (&symbol_list_obstack);
|
||||
obstack_init (&cache_space);
|
||||
|
||||
decoded_names_store = htab_create_alloc_ex
|
||||
(256, htab_hash_string, (int (*) (const void *, const void *)) streq,
|
||||
|
@ -124,6 +124,41 @@ struct ada_symbol_info {
|
||||
struct symtab* symtab;
|
||||
};
|
||||
|
||||
/* Ada task structures. */
|
||||
|
||||
/* Ada task control block, as defined in the GNAT runt-time library. */
|
||||
|
||||
struct task_control_block
|
||||
{
|
||||
char state;
|
||||
CORE_ADDR parent;
|
||||
int priority;
|
||||
char image [32];
|
||||
int image_len; /* This field is not always present in the ATCB. */
|
||||
CORE_ADDR call;
|
||||
CORE_ADDR thread;
|
||||
CORE_ADDR lwp; /* This field is not always present in the ATCB. */
|
||||
};
|
||||
|
||||
struct task_ptid
|
||||
{
|
||||
int pid; /* The Process id */
|
||||
long lwp; /* The Light Weight Process id */
|
||||
long tid; /* The Thread id */
|
||||
};
|
||||
typedef struct task_ptid task_ptid_t;
|
||||
|
||||
struct task_entry
|
||||
{
|
||||
CORE_ADDR task_id;
|
||||
struct task_control_block atcb;
|
||||
int task_num;
|
||||
int known_tasks_index;
|
||||
struct task_entry *next_task;
|
||||
task_ptid_t task_ptid;
|
||||
int stack_per;
|
||||
};
|
||||
|
||||
extern struct type *builtin_type_ada_int;
|
||||
extern struct type *builtin_type_ada_short;
|
||||
extern struct type *builtin_type_ada_long;
|
||||
@ -136,9 +171,13 @@ extern struct type *builtin_type_ada_natural;
|
||||
extern struct type *builtin_type_ada_positive;
|
||||
extern struct type *builtin_type_ada_system_address;
|
||||
|
||||
/* The maximum number of tasks known to the Ada runtime */
|
||||
/* The maximum number of tasks known to the Ada runtime. */
|
||||
extern const int MAX_NUMBER_OF_KNOWN_TASKS;
|
||||
|
||||
/* task entry list. */
|
||||
extern struct task_entry *task_list;
|
||||
|
||||
|
||||
/* Assuming V points to an array of S objects, make sure that it contains at
|
||||
least M objects, updating V and S as necessary. */
|
||||
|
||||
@ -393,6 +432,8 @@ extern void ada_find_printable_frame (struct frame_info *fi);
|
||||
|
||||
extern void ada_reset_thread_registers (void);
|
||||
|
||||
extern int ada_build_task_list (void);
|
||||
|
||||
/* Look up a symbol by name using the search conventions of
|
||||
a specific language (optional block, optional symtab).
|
||||
FIXME: Should be symtab.h. */
|
||||
@ -403,5 +444,4 @@ extern struct symbol *lookup_symbol_in_language (const char *,
|
||||
enum language,
|
||||
int *,
|
||||
struct symtab **);
|
||||
|
||||
#endif
|
||||
|
@ -62,18 +62,6 @@ enum task_states
|
||||
Master_Phase_2_Sleep
|
||||
};
|
||||
|
||||
struct task_control_block
|
||||
{
|
||||
char state;
|
||||
CORE_ADDR parent;
|
||||
int priority;
|
||||
char image [32];
|
||||
int image_len; /* This field is not always present in the ATCB. */
|
||||
CORE_ADDR call;
|
||||
CORE_ADDR thread;
|
||||
CORE_ADDR lwp; /* This field is not always present in the ATCB. */
|
||||
};
|
||||
|
||||
/* The index of certain important fields in the Ada Task Control Block
|
||||
record and sub-records. */
|
||||
|
||||
@ -102,25 +90,6 @@ struct tcb_fieldnos
|
||||
#define TASK_LWP(atcb) extract_unsigned_integer (&(atcb).lwp, sizeof ((atcb).lwp))
|
||||
#endif
|
||||
|
||||
struct task_ptid
|
||||
{
|
||||
int pid; /* The Process id */
|
||||
long lwp; /* The Light Weight Process id */
|
||||
long tid; /* The Thread id */
|
||||
};
|
||||
typedef struct task_ptid task_ptid_t;
|
||||
|
||||
struct task_entry
|
||||
{
|
||||
CORE_ADDR task_id;
|
||||
struct task_control_block atcb;
|
||||
int task_num;
|
||||
int known_tasks_index;
|
||||
struct task_entry *next_task;
|
||||
task_ptid_t task_ptid;
|
||||
int stack_per;
|
||||
};
|
||||
|
||||
/* FIXME: move all this conditional compilation in description
|
||||
files or in configure.in */
|
||||
|
||||
@ -267,7 +236,6 @@ static void get_tcb_call_type_info (struct type **atcb_call_type,
|
||||
int *atcb_call_self_fieldno);
|
||||
static CORE_ADDR get_known_tasks_addr (void);
|
||||
static int read_known_tasks_array (void);
|
||||
static int build_task_list (void);
|
||||
static void value_as_string (char *dest, struct value *val, int length);
|
||||
static struct task_control_block read_atcb (CORE_ADDR atcb_addr);
|
||||
static CORE_ADDR read_caller (const CORE_ADDR call);
|
||||
@ -283,9 +251,9 @@ static void ada_tasks_attach_observers (void);
|
||||
|
||||
int ada__tasks_check_symbol_table = 1;
|
||||
CORE_ADDR pthread_kern_addr = 0;
|
||||
struct task_entry *task_list = NULL;
|
||||
|
||||
/* Local global variables. */
|
||||
static struct task_entry *task_list = NULL;
|
||||
|
||||
/* When non-zero, this flag indicates that the current task_list
|
||||
is obsolete, and should be recomputed before it is accessed. */
|
||||
@ -850,8 +818,8 @@ read_known_tasks_array (void)
|
||||
the inferior. Prints an appropriate message and returns non-zero
|
||||
if it failed to build this list. */
|
||||
|
||||
static int
|
||||
build_task_list (void)
|
||||
int
|
||||
ada_build_task_list (void)
|
||||
{
|
||||
if (!target_has_stack)
|
||||
error ("No stack");
|
||||
@ -1306,7 +1274,7 @@ info_tasks (char *arg, int from_tty)
|
||||
static void
|
||||
info_tasks_command (char *arg, int from_tty)
|
||||
{
|
||||
const int task_list_built = build_task_list ();
|
||||
const int task_list_built = ada_build_task_list ();
|
||||
|
||||
if (!task_list_built)
|
||||
return;
|
||||
@ -1358,13 +1326,10 @@ switch_to_task (struct task_entry *new_task)
|
||||
select_frame (get_current_frame ());
|
||||
return ret_code;
|
||||
}
|
||||
else if (task_ptid_get_pid (new_task->task_ptid) != 0) /* ?? */
|
||||
{
|
||||
switch_to_thread (task_ptid_get_ptid (new_task->task_ptid));
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch_to_thread (task_ptid_get_ptid (new_task->task_ptid));
|
||||
#endif
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Print a message telling the user id of the current task.
|
||||
@ -1412,7 +1377,7 @@ task_command_1 (char *tidstr, int from_tty)
|
||||
static void
|
||||
task_command (char *tidstr, int from_tty)
|
||||
{
|
||||
const int task_list_built = build_task_list ();
|
||||
const int task_list_built = ada_build_task_list ();
|
||||
|
||||
if (!task_list_built)
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user