/* Parser for linespec for the GNU debugger, GDB.
- Copyright (C) 1986-2015 Free Software Foundation, Inc.
+ Copyright (C) 1986-2016 Free Software Foundation, Inc.
This file is part of GDB.
struct linespec
{
/* An explicit location describing the SaLs. */
- struct explicit_location explicit;
+ struct explicit_location explicit_loc;
/* The list of symtabs to search to which to limit the search. May not
be NULL. If explicit.SOURCE_FILENAME is NULL (no user-specified
/* The program space as seen when the module was entered. */
struct program_space *program_space;
+ /* If not NULL, the search is restricted to just this program
+ space. */
+ struct program_space *search_pspace;
+
/* The default symtab to use, if no other symtab is specified. */
struct symtab *default_symtab;
/* A convenience macro for accessing the explicit location result of
the parser. */
-#define PARSER_EXPLICIT(PPTR) (&PARSER_RESULT ((PPTR))->explicit)
+#define PARSER_EXPLICIT(PPTR) (&PARSER_RESULT ((PPTR))->explicit_loc)
/* Prototypes for local functions. */
linespec_p ls,
const char *arg);
-static VEC (symtab_ptr) *symtabs_from_filename (const char *);
+static VEC (symtab_ptr) *symtabs_from_filename (const char *,
+ struct program_space *pspace);
static VEC (symbolp) *find_label_symbols (struct linespec_state *self,
VEC (symbolp) *function_symbols,
struct program_space *pspace,
VEC (const_char_ptr) *names);
-static VEC (symtab_ptr) *collect_symtabs_from_filename (const char *file);
+static VEC (symtab_ptr) *
+ collect_symtabs_from_filename (const char *file,
+ struct program_space *pspace);
static void decode_digits_ordinary (struct linespec_state *self,
linespec_p ls,
&& (PARSER_STREAM (parser) - start) > 8
/* strlen ("operator") */)
{
- char *p = strstr (start, "operator");
+ const char *p = strstr (start, "operator");
if (p != NULL && is_operator_name (p))
{
struct symtab_and_line *sal)
{
++sals->nelts;
- sals->sals = xrealloc (sals->sals, sals->nelts * sizeof (sals->sals[0]));
+ sals->sals = XRESIZEVEC (struct symtab_and_line, sals->sals, sals->nelts);
sals->sals[sals->nelts - 1] = *sal;
}
{
struct linespec_canonical_name *canonical;
- self->canonical_names = xrealloc (self->canonical_names,
- (sals->nelts
- * sizeof (*self->canonical_names)));
+ self->canonical_names = XRESIZEVEC (struct linespec_canonical_name,
+ self->canonical_names, sals->nelts);
canonical = &self->canonical_names[sals->nelts - 1];
if (!literal_canonical && sal->symtab)
{
- const char *fullname = symtab_to_fullname (sal->symtab);
+ symtab_to_fullname (sal->symtab);
/* Note that the filter doesn't have to be a valid linespec
input. We only apply the ":LINE" treatment to Ada for
static hashval_t
hash_address_entry (const void *p)
{
- const struct address_entry *aep = p;
+ const struct address_entry *aep = (const struct address_entry *) p;
hashval_t hash;
hash = iterative_hash_object (aep->pspace, 0);
static int
eq_address_entry (const void *a, const void *b)
{
- const struct address_entry *aea = a;
- const struct address_entry *aeb = b;
+ const struct address_entry *aea = (const struct address_entry *) a;
+ const struct address_entry *aeb = (const struct address_entry *) b;
return aea->pspace == aeb->pspace && aea->addr == aeb->addr;
}
{
if (SYMBOL_INLINED (sym))
{
- struct symbol_and_data_callback *cad = d;
+ struct symbol_and_data_callback *cad
+ = (struct symbol_and_data_callback *) d;
return cad->callback (sym, cad->data);
}
static int
iterate_name_matcher (const char *name, void *d)
{
- const struct symbol_matcher_data *data = d;
+ const struct symbol_matcher_data *data
+ = (const struct symbol_matcher_data *) d;
if (data->symbol_name_cmp (name, data->lookup_name) == 0)
return 1; /* Expand this symbol's symbol table. */
static int
decode_line_2_compare_items (const void *ap, const void *bp)
{
- const struct decode_line_2_item *a = ap;
- const struct decode_line_2_item *b = bp;
+ const struct decode_line_2_item *a = (const struct decode_line_2_item *) ap;
+ const struct decode_line_2_item *b = (const struct decode_line_2_item *) bp;
int retval;
retval = strcmp (a->displayform, b->displayform);
/* Prepare ITEMS array. */
items_count = result->nelts;
- items = xmalloc (sizeof (*items) * items_count);
+ items = XNEWVEC (struct decode_line_2_item, items_count);
make_cleanup (xfree, items);
for (i = 0; i < items_count; ++i)
{
|| token.type == LSTOKEN_KEYWORD)
{
char *string;
- struct cleanup *cleanup;
string = copy_token_string (token);
- cleanup = make_cleanup (xfree, string);
+ make_cleanup (xfree, string);
throw_error (GENERIC_ERROR,
_("malformed linespec error: unexpected %s, \"%s\""),
token_type_strings[token.type], string);
canonicalize_linespec (struct linespec_state *state, const linespec_p ls)
{
struct event_location *canon;
- struct explicit_location *explicit;
+ struct explicit_location *explicit_loc;
/* If canonicalization was not requested, no need to do anything. */
if (!state->canonical)
return;
/* Save everything as an explicit location. */
- canon = state->canonical->location = new_explicit_location (&ls->explicit);
- explicit = get_explicit_location (canon);
+ canon = state->canonical->location
+ = new_explicit_location (&ls->explicit_loc);
+ explicit_loc = get_explicit_location (canon);
- if (explicit->label_name != NULL)
+ if (explicit_loc->label_name != NULL)
{
state->canonical->special_display = 1;
- if (explicit->function_name == NULL)
+ if (explicit_loc->function_name == NULL)
{
struct symbol *s;
&& (VEC_length (symbolp, ls->labels.function_symbols)
== 1));
s = VEC_index (symbolp, ls->labels.function_symbols, 0);
- explicit->function_name = xstrdup (SYMBOL_NATURAL_NAME (s));
+ explicit_loc->function_name = xstrdup (SYMBOL_NATURAL_NAME (s));
}
}
representation of it for display and saving to file. */
if (state->is_linespec)
{
- char *linespec = explicit_location_to_linespec (explicit);
+ char *linespec = explicit_location_to_linespec (explicit_loc);
set_event_location_string (canon, linespec);
xfree (linespec);
fullname = symtab_to_fullname (self->default_symtab);
VEC_pop (symtab_ptr, ls->file_symtabs);
VEC_free (symtab_ptr, ls->file_symtabs);
- ls->file_symtabs = collect_symtabs_from_filename (fullname);
+ ls->file_symtabs = collect_symtabs_from_filename (fullname,
+ self->search_pspace);
use_default = 1;
}
- val.line = ls->explicit.line_offset.offset;
- switch (ls->explicit.line_offset.sign)
+ val.line = ls->explicit_loc.line_offset.offset;
+ switch (ls->explicit_loc.line_offset.sign)
{
case LINE_OFFSET_PLUS:
- if (ls->explicit.line_offset.offset == 0)
+ if (ls->explicit_loc.line_offset.offset == 0)
val.line = 5;
if (use_default)
val.line = self->default_line + val.line;
break;
case LINE_OFFSET_MINUS:
- if (ls->explicit.line_offset.offset == 0)
+ if (ls->explicit_loc.line_offset.offset == 0)
val.line = 15;
if (use_default)
val.line = self->default_line - val.line;
if (values.nelts == 0)
{
- if (ls->explicit.source_filename)
+ if (ls->explicit_loc.source_filename)
throw_error (NOT_FOUND_ERROR, _("No line %d in file \"%s\"."),
- val.line, ls->explicit.source_filename);
+ val.line, ls->explicit_loc.source_filename);
else
throw_error (NOT_FOUND_ERROR, _("No line %d in the current file."),
val.line);
}
}
}
- else if (ls->explicit.line_offset.sign != LINE_OFFSET_UNKNOWN)
+ else if (ls->explicit_loc.line_offset.sign != LINE_OFFSET_UNKNOWN)
{
/* Only an offset was specified. */
sals = create_sals_line_offset (state, ls);
/* Make sure we have a filename for canonicalization. */
- if (ls->explicit.source_filename == NULL)
+ if (ls->explicit_loc.source_filename == NULL)
{
const char *fullname = symtab_to_fullname (state->default_symtab);
form so that displaying SOURCE_FILENAME can follow the current
FILENAME_DISPLAY_STRING setting. But as it is used only rarely
it has been kept for code simplicity only in absolute form. */
- ls->explicit.source_filename = xstrdup (fullname);
+ ls->explicit_loc.source_filename = xstrdup (fullname);
}
}
else
return sals;
}
-/* Convert the explicit location EXPLICIT into SaLs. */
+/* Convert the explicit location EXPLICIT_LOC into SaLs. */
static struct symtabs_and_lines
convert_explicit_location_to_sals (struct linespec_state *self,
linespec_p result,
- const struct explicit_location *explicit)
+ const struct explicit_location *explicit_loc)
{
VEC (symbolp) *symbols, *labels;
VEC (bound_minimal_symbol_d) *minimal_symbols;
- if (explicit->source_filename != NULL)
+ if (explicit_loc->source_filename != NULL)
{
TRY
{
result->file_symtabs
- = symtabs_from_filename (explicit->source_filename);
+ = symtabs_from_filename (explicit_loc->source_filename,
+ self->search_pspace);
}
CATCH (except, RETURN_MASK_ERROR)
{
- source_file_not_found_error (explicit->source_filename);
+ source_file_not_found_error (explicit_loc->source_filename);
}
END_CATCH
- result->explicit.source_filename = xstrdup (explicit->source_filename);
+ result->explicit_loc.source_filename
+ = xstrdup (explicit_loc->source_filename);
}
else
{
VEC_safe_push (symtab_ptr, result->file_symtabs, NULL);
}
- if (explicit->function_name != NULL)
+ if (explicit_loc->function_name != NULL)
{
find_linespec_symbols (self, result->file_symtabs,
- explicit->function_name, &symbols,
+ explicit_loc->function_name, &symbols,
&minimal_symbols);
if (symbols == NULL && minimal_symbols == NULL)
- symbol_not_found_error (explicit->function_name,
- result->explicit.source_filename);
+ symbol_not_found_error (explicit_loc->function_name,
+ result->explicit_loc.source_filename);
- result->explicit.function_name = xstrdup (explicit->function_name);
+ result->explicit_loc.function_name
+ = xstrdup (explicit_loc->function_name);
result->function_symbols = symbols;
result->minimal_symbols = minimal_symbols;
}
- if (explicit->label_name != NULL)
+ if (explicit_loc->label_name != NULL)
{
symbols = NULL;
labels = find_label_symbols (self, result->function_symbols,
- &symbols, explicit->label_name);
+ &symbols, explicit_loc->label_name);
if (labels == NULL)
- undefined_label_error (result->explicit.function_name,
- explicit->label_name);
+ undefined_label_error (result->explicit_loc.function_name,
+ explicit_loc->label_name);
- result->explicit.label_name = xstrdup (explicit->label_name);
+ result->explicit_loc.label_name = xstrdup (explicit_loc->label_name);
result->labels.label_symbols = labels;
result->labels.function_symbols = symbols;
}
- if (explicit->line_offset.sign != LINE_OFFSET_UNKNOWN)
- result->explicit.line_offset = explicit->line_offset;
+ if (explicit_loc->line_offset.sign != LINE_OFFSET_UNKNOWN)
+ result->explicit_loc.line_offset = explicit_loc->line_offset;
return convert_linespec_to_sals (self, result);
}
TRY
{
PARSER_RESULT (parser)->file_symtabs
- = symtabs_from_filename (user_filename);
+ = symtabs_from_filename (user_filename,
+ PARSER_STATE (parser)->search_pspace);
}
CATCH (ex, RETURN_MASK_ERROR)
{
static void
linespec_state_constructor (struct linespec_state *self,
int flags, const struct language_defn *language,
+ struct program_space *search_pspace,
struct symtab *default_symtab,
int default_line,
struct linespec_result *canonical)
self->language = language;
self->funfirstline = (flags & DECODE_LINE_FUNFIRSTLINE) ? 1 : 0;
self->list_mode = (flags & DECODE_LINE_LIST_MODE) ? 1 : 0;
+ self->search_pspace = search_pspace;
self->default_symtab = default_symtab;
self->default_line = default_line;
self->canonical = canonical;
static void
linespec_parser_new (linespec_parser *parser,
int flags, const struct language_defn *language,
+ struct program_space *search_pspace,
struct symtab *default_symtab,
int default_line,
struct linespec_result *canonical)
memset (PARSER_RESULT (parser), 0, sizeof (struct linespec));
PARSER_EXPLICIT (parser)->line_offset.sign = LINE_OFFSET_UNKNOWN;
linespec_state_constructor (PARSER_STATE (parser), flags, language,
+ search_pspace,
default_symtab, default_line, canonical);
}
if (stringp == NULL || *stringp == NULL)
return;
- linespec_parser_new (&parser, 0, current_language, NULL, 0, NULL);
+ linespec_parser_new (&parser, 0, current_language, NULL, NULL, 0, NULL);
cleanup = make_cleanup (linespec_parser_delete, &parser);
parser.lexer.saved_arg = *stringp;
PARSER_STREAM (&parser) = orig = *stringp;
break;
case ADDRESS_LOCATION:
- result
- = convert_address_location_to_sals (PARSER_STATE (parser),
- get_address_location (location));
+ {
+ const char *addr_string = get_address_string_location (location);
+ CORE_ADDR addr = get_address_location (location);
+
+ if (addr_string != NULL)
+ {
+ char *expr = xstrdup (addr_string);
+ const char *const_expr = expr;
+ struct cleanup *cleanup = make_cleanup (xfree, expr);
+
+ addr = linespec_expression_to_pc (&const_expr);
+ if (PARSER_STATE (parser)->canonical != NULL)
+ PARSER_STATE (parser)->canonical->location
+ = copy_event_location (location);
+
+ do_cleanups (cleanup);
+ }
+
+ result = convert_address_location_to_sals (PARSER_STATE (parser),
+ addr);
+ }
break;
case EXPLICIT_LOCATION:
{
- const struct explicit_location *explicit;
+ const struct explicit_location *explicit_loc;
- explicit = get_explicit_location_const (location);
+ explicit_loc = get_explicit_location_const (location);
result = convert_explicit_location_to_sals (PARSER_STATE (parser),
PARSER_RESULT (parser),
- explicit);
+ explicit_loc);
}
break;
void
decode_line_full (const struct event_location *location, int flags,
+ struct program_space *search_pspace,
struct symtab *default_symtab,
int default_line, struct linespec_result *canonical,
const char *select_mode,
|| select_mode == multiple_symbols_cancel);
gdb_assert ((flags & DECODE_LINE_LIST_MODE) == 0);
- linespec_parser_new (&parser, flags, current_language, default_symtab,
+ linespec_parser_new (&parser, flags, current_language,
+ search_pspace, default_symtab,
default_line, canonical);
cleanups = make_cleanup (linespec_parser_delete, &parser);
save_current_program_space ();
struct symtabs_and_lines
decode_line_1 (const struct event_location *location, int flags,
+ struct program_space *search_pspace,
struct symtab *default_symtab,
int default_line)
{
linespec_parser parser;
struct cleanup *cleanups;
- linespec_parser_new (&parser, flags, current_language, default_symtab,
+ linespec_parser_new (&parser, flags, current_language,
+ search_pspace, default_symtab,
default_line, NULL);
cleanups = make_cleanup (linespec_parser_delete, &parser);
save_current_program_space ();
location = string_to_event_location (&string, current_language);
cleanup = make_cleanup_delete_event_location (location);
- sals = decode_line_1 (location, flags,
+ sals = decode_line_1 (location, flags, NULL,
cursal.symtab, cursal.line);
if (*string)
location = string_to_event_location (&string, current_language);
cleanup = make_cleanup_delete_event_location (location);
if (last_displayed_sal_is_valid ())
- sals = decode_line_1 (location, flags,
+ sals = decode_line_1 (location, flags, NULL,
get_last_displayed_symtab (),
get_last_displayed_line ());
else
- sals = decode_line_1 (location, flags, (struct symtab *) NULL, 0);
+ sals = decode_line_1 (location, flags, NULL, (struct symtab *) NULL, 0);
if (*string)
error (_("Junk at end of line specification: %s"), string);
{
char *saved_arg;
- saved_arg = alloca (new_argptr - arg + 1);
+ saved_arg = (char *) alloca (new_argptr - arg + 1);
memcpy (saved_arg, arg, new_argptr - arg);
saved_arg[new_argptr - arg] = '\0';
- ls->explicit.function_name = xstrdup (saved_arg);
+ ls->explicit_loc.function_name = xstrdup (saved_arg);
ls->function_symbols = info.result.symbols;
ls->minimal_symbols = info.result.minimal_symbols;
values = convert_linespec_to_sals (self, ls);
self->canonical->pre_expanded = 1;
- if (ls->explicit.source_filename)
+ if (ls->explicit_loc.source_filename)
{
str = xstrprintf ("%s:%s",
- ls->explicit.source_filename, saved_arg);
+ ls->explicit_loc.source_filename, saved_arg);
}
else
str = xstrdup (saved_arg);
static int
collect_one_symbol (struct symbol *sym, void *d)
{
- struct decode_compound_collector *collector = d;
+ struct decode_compound_collector *collector
+ = (struct decode_compound_collector *) d;
void **slot;
struct type *t;
static int
compare_symbols (const void *a, const void *b)
{
- struct symbol * const *sa = a;
- struct symbol * const *sb = b;
+ struct symbol * const *sa = (struct symbol * const*) a;
+ struct symbol * const *sb = (struct symbol * const*) b;
uintptr_t uia, uib;
uia = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (*sa));
static int
compare_msymbols (const void *a, const void *b)
{
- const struct bound_minimal_symbol *sa = a;
- const struct bound_minimal_symbol *sb = b;
+ const struct bound_minimal_symbol *sa
+ = (const struct bound_minimal_symbol *) a;
+ const struct bound_minimal_symbol *sb
+ = (const struct bound_minimal_symbol *) b;
uintptr_t uia, uib;
uia = (uintptr_t) sa->objfile->pspace;
static int
add_symtabs_to_list (struct symtab *symtab, void *d)
{
- struct symtab_collector *data = d;
+ struct symtab_collector *data = (struct symtab_collector *) d;
void **slot;
slot = htab_find_slot (data->symtab_table, symtab, INSERT);
return 0;
}
-/* Given a file name, return a VEC of all matching symtabs. */
+/* Given a file name, return a VEC of all matching symtabs. If
+ SEARCH_PSPACE is not NULL, the search is restricted to just that
+ program space. */
static VEC (symtab_ptr) *
-collect_symtabs_from_filename (const char *file)
+collect_symtabs_from_filename (const char *file,
+ struct program_space *search_pspace)
{
struct symtab_collector collector;
struct cleanup *cleanups;
cleanups = make_cleanup_htab_delete (collector.symtab_table);
/* Find that file's data. */
- ALL_PSPACES (pspace)
- {
- if (pspace->executing_startup)
- continue;
+ if (search_pspace == NULL)
+ {
+ ALL_PSPACES (pspace)
+ {
+ if (pspace->executing_startup)
+ continue;
- set_current_program_space (pspace);
- iterate_over_symtabs (file, add_symtabs_to_list, &collector);
- }
+ set_current_program_space (pspace);
+ iterate_over_symtabs (file, add_symtabs_to_list, &collector);
+ }
+ }
+ else
+ {
+ set_current_program_space (search_pspace);
+ iterate_over_symtabs (file, add_symtabs_to_list, &collector);
+ }
do_cleanups (cleanups);
return collector.symtabs;
}
-/* Return all the symtabs associated to the FILENAME. */
+/* Return all the symtabs associated to the FILENAME. If SEARCH_PSPACE is
+ not NULL, the search is restricted to just that program space. */
static VEC (symtab_ptr) *
-symtabs_from_filename (const char *filename)
+symtabs_from_filename (const char *filename,
+ struct program_space *search_pspace)
{
VEC (symtab_ptr) *result;
- result = collect_symtabs_from_filename (filename);
+ result = collect_symtabs_from_filename (filename, search_pspace);
if (VEC_empty (symtab_ptr, result))
{
/* Try NAME as an Objective-C selector. */
find_imps (name, &symbol_names);
if (!VEC_empty (const_char_ptr, symbol_names))
- add_all_symbol_names_from_pspace (&info, NULL, symbol_names);
+ add_all_symbol_names_from_pspace (&info, state->search_pspace,
+ symbol_names);
else
- add_matching_symbols_to_info (name, &info, NULL);
+ add_matching_symbols_to_info (name, &info, state->search_pspace);
do_cleanups (cleanup);
name into namespaces${SCOPE_OPERATOR}class_name and method_name. */
scope_op = "::";
p = find_toplevel_string (lookup_name, scope_op);
- if (p == NULL)
- {
- /* No C++ scope operator. Try Java. */
- scope_op = ".";
- p = find_toplevel_string (lookup_name, scope_op);
- }
last = NULL;
while (p != NULL)
/* LOOKUP_NAME points to the class name.
LAST points to the method name. */
- klass = xmalloc ((last - lookup_name + 1) * sizeof (char));
+ klass = XNEWVEC (char, last - lookup_name + 1);
make_cleanup (xfree, klass);
strncpy (klass, lookup_name, last - lookup_name);
klass[last - lookup_name] = '\0';
/* Skip past the scope operator. */
last += strlen (scope_op);
- method = xmalloc ((strlen (last) + 1) * sizeof (char));
+ method = XNEWVEC (char, strlen (last) + 1);
make_cleanup (xfree, method);
strcpy (method, last);
static int
collect_symbols (struct symbol *sym, void *data)
{
- struct collect_info *info = data;
+ struct collect_info *info = (struct collect_info *) data;
/* In list mode, add all matching symbols, regardless of class.
This allows the user to type "list a_global_variable". */
sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
sal.pc = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc,
¤t_target);
+ if (gdbarch_skip_entrypoint_p (gdbarch))
+ sal.pc = gdbarch_skip_entrypoint (gdbarch, sal.pc);
}
else
skip_prologue_sal (&sal);
static int
compare_msyms (const void *a, const void *b)
{
- const bound_minimal_symbol_d *moa = a;
- const bound_minimal_symbol_d *mob = b;
+ const bound_minimal_symbol_d *moa = (const bound_minimal_symbol_d *) a;
+ const bound_minimal_symbol_d *mob = (const bound_minimal_symbol_d *) b;
enum minimal_symbol_type ta = MSYMBOL_TYPE (moa->minsym);
enum minimal_symbol_type tb = MSYMBOL_TYPE (mob->minsym);
static void
add_minsym (struct minimal_symbol *minsym, void *d)
{
- struct collect_minsyms *info = d;
+ struct collect_minsyms *info = (struct collect_minsyms *) d;
bound_minimal_symbol_d mo;
mo.minsym = minsym;
static void
cleanup_linespec_result (void *a)
{
- destroy_linespec_result (a);
+ destroy_linespec_result ((struct linespec_result *) a);
}
/* See the comment in linespec.h. */