summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Seitz <keiths@redhat.com>2015-09-30 14:23:12 -0700
committerKeith Seitz <keiths@redhat.com>2015-10-01 11:48:39 -0700
commit23916b7dc0f2f05982da7a76726d931cf738d2cc (patch)
treeb08bad1994250bf0a7d849fe099fd6f5c2d7da80
parent398e081380a204e3b9fb4eb4da069ccf471f930e (diff)
downloadbinutils-gdb-users/keiths/intelligent-breakpoint_re_set.tar.gz
Initial publication of breakpoint reset project.users/keiths/intelligent-breakpoint_re_set
This is a work-in-progress publication of an intelligent breakpoint_re_set redesign. See the project wiki page for more information: https://sourceware.org/gdb/wiki/BreakpointReset
-rw-r--r--gdb/ada-lang.c13
-rw-r--r--gdb/ax-gdb.c6
-rw-r--r--gdb/break-catch-throw.c9
-rw-r--r--gdb/breakpoint.c242
-rw-r--r--gdb/breakpoint.h32
-rw-r--r--gdb/cli/cli-cmds.c23
-rw-r--r--gdb/common/gdb_vecs.h4
-rw-r--r--gdb/dwarf2read.c3
-rw-r--r--gdb/infcmd.c5
-rw-r--r--gdb/infrun.c29
-rw-r--r--gdb/linespec.c525
-rw-r--r--gdb/linespec.h77
-rw-r--r--gdb/minsyms.h3
-rw-r--r--gdb/objfiles.c16
-rw-r--r--gdb/python/python.c8
-rw-r--r--gdb/solib.c19
-rw-r--r--gdb/symfile.c28
-rw-r--r--gdb/symtab.c130
-rw-r--r--gdb/symtab.h4
-rw-r--r--gdb/tracepoint.c4
20 files changed, 917 insertions, 263 deletions
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index a229fa1243d..fd712fe39b1 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -12248,11 +12248,13 @@ allocate_location_exception (enum ada_exception_catchpoint_kind ex,
static void
re_set_exception (enum ada_exception_catchpoint_kind ex, struct breakpoint *b)
{
+ struct breakpoint_reset_reason reset_reason;
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
/* Call the base class's method. This updates the catchpoint's
locations. */
- bkpt_breakpoint_ops.re_set (b);
+ init_breakpoint_reset_reason (&reset_reason);
+ bkpt_breakpoint_ops.re_set (b, &reset_reason);
/* Reparse the exception conditional expressions. One for each
location. */
@@ -12522,7 +12524,8 @@ allocate_location_catch_exception (struct breakpoint *self)
}
static void
-re_set_catch_exception (struct breakpoint *b)
+re_set_catch_exception (struct breakpoint *b,
+ struct breakpoint_reset_reason *reason)
{
re_set_exception (ada_catch_exception, b);
}
@@ -12574,7 +12577,8 @@ allocate_location_catch_exception_unhandled (struct breakpoint *self)
}
static void
-re_set_catch_exception_unhandled (struct breakpoint *b)
+re_set_catch_exception_unhandled (struct breakpoint *b,
+ struct breakpoint_reset_reason *reason)
{
re_set_exception (ada_catch_exception_unhandled, b);
}
@@ -12628,7 +12632,8 @@ allocate_location_catch_assert (struct breakpoint *self)
}
static void
-re_set_catch_assert (struct breakpoint *b)
+re_set_catch_assert (struct breakpoint *b,
+ struct breakpoint_reset_reason *reason)
{
re_set_exception (ada_catch_assert, b);
}
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 817fa53ed90..70c351f6ab8 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -2644,14 +2644,14 @@ agent_command_1 (char *exp, int eval)
struct linespec_sals *iter;
struct cleanup *old_chain;
struct event_location *location;
+ struct decode_line_options opts;
exp = skip_spaces (exp);
init_linespec_result (&canonical);
location = new_linespec_location (&exp);
old_chain = make_cleanup_delete_event_location (location);
- decode_line_full (location, DECODE_LINE_FUNFIRSTLINE,
- (struct symtab *) NULL, 0, &canonical,
- NULL, NULL);
+ init_decode_line_options (&opts);
+ decode_line_full (location, &canonical, &opts);
make_cleanup_destroy_linespec_result (&canonical);
exp = skip_spaces (exp);
if (exp[0] == ',')
diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c
index 1ba505b6e49..e2668b524a2 100644
--- a/gdb/break-catch-throw.c
+++ b/gdb/break-catch-throw.c
@@ -205,7 +205,8 @@ check_status_exception_catchpoint (struct bpstats *bs)
/* Implement the 're_set' method. */
static void
-re_set_exception_catchpoint (struct breakpoint *self)
+re_set_exception_catchpoint (struct breakpoint *self,
+ struct breakpoint_reset_reason *reason)
{
struct symtabs_and_lines sals = {0};
struct symtabs_and_lines sals_end = {0};
@@ -236,7 +237,7 @@ re_set_exception_catchpoint (struct breakpoint *self)
= ASTRDUP (exception_functions[kind].function);
location = new_explicit_location (&explicit_loc);
cleanup = make_cleanup_delete_event_location (location);
- self->ops->decode_location (self, location, &sals);
+ self->ops->decode_location (self, location, NULL, &sals);
do_cleanups (cleanup);
}
CATCH (ex, RETURN_MASK_ERROR)
@@ -393,6 +394,7 @@ static void
handle_gnu_v3_exceptions (int tempflag, char *except_rx, char *cond_string,
enum exception_event_kind ex_event, int from_tty)
{
+ struct breakpoint_reset_reason reset_reason;
struct exception_catchpoint *cp;
struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
regex_t *pattern = NULL;
@@ -418,7 +420,8 @@ handle_gnu_v3_exceptions (int tempflag, char *except_rx, char *cond_string,
cp->exception_rx = except_rx;
cp->pattern = pattern;
- re_set_exception_catchpoint (&cp->base);
+ init_breakpoint_reset_reason (&reset_reason);
+ re_set_exception_catchpoint (&cp->base, &reset_reason);
install_breakpoint (0, &cp->base, 1);
discard_cleanups (cleanup);
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 2c901ff5f2f..eda45d4f9f4 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -80,6 +80,8 @@
#include "mi/mi-common.h"
#include "extension.h"
+#define DEBUG_ME 0
+
/* Enums for exception-handling support. */
enum exception_event_kind
{
@@ -88,6 +90,17 @@ enum exception_event_kind
EX_EVENT_CATCH
};
+/* Structure to wrap arguments to breakpoint_reset_one via catch_errors. */
+
+struct breakpoint_re_set_one_info
+{
+ /* The breakpoint to re-set. */
+ struct breakpoint *bp;
+
+ /* The reason for re-setting this breakpoint. */
+ struct breakpoint_reset_reason *reason;
+};
+
/* Prototypes for local functions. */
static void enable_delete_command (char *, int);
@@ -108,7 +121,8 @@ static void ignore_command (char *, int);
static int breakpoint_re_set_one (void *);
-static void breakpoint_re_set_default (struct breakpoint *);
+static void breakpoint_re_set_default (struct breakpoint *,
+ struct breakpoint_reset_reason *);
static void
create_sals_from_location_default (const struct event_location *location,
@@ -125,6 +139,7 @@ static void create_breakpoints_sal_default (struct gdbarch *,
static void decode_location_default (struct breakpoint *b,
const struct event_location *location,
+ const struct decode_line_limits *,
struct symtabs_and_lines *sals);
static void clear_command (char *, int);
@@ -3101,7 +3116,7 @@ insert_breakpoint_locations (void)
struct ui_file *tmp_error_stream = mem_fileopen ();
struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_error_stream);
-
+
/* Explicitly mark the warning -- this will only be printed if
there was an error. */
fprintf_unfiltered (tmp_error_stream, "Warning:\n");
@@ -8770,8 +8785,12 @@ disable_breakpoints_before_startup (void)
void
enable_breakpoints_after_startup (void)
{
+ struct breakpoint_reset_reason r;
+
+ init_breakpoint_reset_reason (&r);
+ r.where = __func__;
current_program_space->executing_startup = 0;
- breakpoint_re_set ();
+ breakpoint_re_set (&r);
}
/* Create a new single-step breakpoint for thread THREAD, with no
@@ -9363,6 +9382,7 @@ parse_breakpoint_sals (const struct event_location *location,
struct linespec_result *canonical)
{
struct symtab_and_line cursal;
+ struct decode_line_options opts;
if (event_location_type (location) == LINESPEC_LOCATION)
{
@@ -9418,6 +9438,12 @@ parse_breakpoint_sals (const struct event_location *location,
ObjC: However, don't match an Objective-C method name which
may have a '+' or '-' succeeded by a '['. */
cursal = get_current_source_symtab_and_line ();
+
+ init_decode_line_options (&opts);
+ opts.default_symtab = cursal.symtab;
+ opts.default_line = cursal.line;
+ opts.flags |= DECODE_LINE_CREATE_CACHE;
+
if (last_displayed_sal_is_valid ())
{
const char *address = NULL;
@@ -9430,16 +9456,19 @@ parse_breakpoint_sals (const struct event_location *location,
&& strchr ("+-", address[0]) != NULL
&& address[1] != '['))
{
- decode_line_full (location, DECODE_LINE_FUNFIRSTLINE,
- get_last_displayed_symtab (),
- get_last_displayed_line (),
- canonical, NULL, NULL);
+ opts.default_symtab = get_last_displayed_symtab ();
+ opts.default_line = get_last_displayed_line ();
+ decode_line_full (location, canonical, &opts);
+ return;
+ }
+ else
+ {
+ decode_line_full (location, canonical, &opts);
return;
}
}
- decode_line_full (location, DECODE_LINE_FUNFIRSTLINE,
- cursal.symtab, cursal.line, canonical, NULL, NULL);
+ decode_line_full (location, canonical, &opts);
}
@@ -9779,6 +9808,17 @@ create_breakpoint (struct gdbarch *gdbarch,
tempflag ? disp_del : disp_donttouch,
thread, task, ignore_count, ops,
from_tty, enabled, internal, flags);
+
+ /* !!keiths; Somewhere here I need to save the linespec cache
+ into the struct. Umm... Need the breakpoint! LAME! */
+ {
+ struct breakpoint *b, *last;
+
+ ALL_BREAKPOINTS (b)
+ last = b;
+ last->linespec_cache = canonical.cache;
+ canonical.cache = NULL;
+ }
}
else
{
@@ -10283,6 +10323,7 @@ break_range_command (char *arg, int from_tty)
struct cleanup *cleanup_bkpt;
struct linespec_sals *lsal_start, *lsal_end;
struct event_location *start_location, *end_location;
+ struct decode_line_options opts;
/* We don't support software ranged breakpoints. */
if (target_ranged_break_num_registers () < 0)
@@ -10337,9 +10378,10 @@ break_range_command (char *arg, int from_tty)
where +14 means 14 lines from the start location. */
end_location = string_to_event_location (&arg, current_language);
make_cleanup_delete_event_location (end_location);
- decode_line_full (end_location, DECODE_LINE_FUNFIRSTLINE,
- sal_start.symtab, sal_start.line,
- &canonical_end, NULL, NULL);
+ init_decode_line_options (&opts);
+ opts.default_symtab = sal_start.symtab;
+ opts.default_line = sal_start.line;
+ decode_line_full (end_location, &canonical_end, &opts);
make_cleanup_destroy_linespec_result (&canonical_end);
@@ -10522,7 +10564,8 @@ dtor_watchpoint (struct breakpoint *self)
/* Implement the "re_set" breakpoint_ops method for watchpoints. */
static void
-re_set_watchpoint (struct breakpoint *b)
+re_set_watchpoint (struct breakpoint *b,
+ struct breakpoint_reset_reason *reason)
{
struct watchpoint *w = (struct watchpoint *) b;
@@ -11591,6 +11634,7 @@ until_break_command (char *arg, int from_tty, int anywhere)
struct thread_info *tp;
struct event_location *location;
struct until_break_fsm *sm;
+ struct decode_line_options options;
clear_proceed_status (0);
@@ -11600,13 +11644,15 @@ until_break_command (char *arg, int from_tty, int anywhere)
location = string_to_event_location (&arg, current_language);
cleanup = make_cleanup_delete_event_location (location);
+ init_decode_line_options (&options);
if (last_displayed_sal_is_valid ())
- sals = decode_line_1 (location, DECODE_LINE_FUNFIRSTLINE,
- get_last_displayed_symtab (),
- get_last_displayed_line ());
+ {
+ options.default_symtab = get_last_displayed_symtab ();
+ options.default_line = get_last_displayed_line ();
+ sals = decode_line_1 (location, &options);
+ }
else
- sals = decode_line_1 (location, DECODE_LINE_FUNFIRSTLINE,
- (struct symtab *) NULL, 0);
+ sals = decode_line_1 (location, &options);
if (sals.nelts != 1)
error (_("Couldn't get information on specified line."));
@@ -12281,7 +12327,6 @@ force_breakpoint_reinsertion (struct bp_location *bl)
/* Called whether new breakpoints are created, or existing breakpoints
deleted, to update the global location list and recompute which
locations are duplicate of which.
-
The INSERT_MODE flag determines whether locations may not, may, or
shall be inserted now. See 'enum ugll_insert_mode' for more
info. */
@@ -12800,7 +12845,8 @@ base_breakpoint_allocate_location (struct breakpoint *self)
}
static void
-base_breakpoint_re_set (struct breakpoint *b)
+base_breakpoint_re_set (struct breakpoint *b,
+ struct breakpoint_reset_reason *reason)
{
/* Nothing to re-set. */
}
@@ -12906,6 +12952,7 @@ base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
static void
base_breakpoint_decode_location (struct breakpoint *b,
const struct event_location *location,
+ const struct decode_line_limits *limits,
struct symtabs_and_lines *sals)
{
internal_error_pure_virtual_called ();
@@ -12953,7 +13000,8 @@ struct breakpoint_ops base_breakpoint_ops =
/* Default breakpoint_ops methods. */
static void
-bkpt_re_set (struct breakpoint *b)
+bkpt_re_set (struct breakpoint *b,
+ struct breakpoint_reset_reason *reason)
{
/* FIXME: is this still reachable? */
if (event_location_empty_p (b->location))
@@ -12963,7 +13011,7 @@ bkpt_re_set (struct breakpoint *b)
return;
}
- breakpoint_re_set_default (b);
+ breakpoint_re_set_default (b, reason);
}
static int
@@ -13153,15 +13201,17 @@ bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
static void
bkpt_decode_location (struct breakpoint *b,
const struct event_location *location,
+ const struct decode_line_limits *limits,
struct symtabs_and_lines *sals)
{
- decode_location_default (b, location, sals);
+ decode_location_default (b, location, limits, sals);
}
/* Virtual table for internal breakpoints. */
static void
-internal_bkpt_re_set (struct breakpoint *b)
+internal_bkpt_re_set (struct breakpoint *b,
+ struct breakpoint_reset_reason *reason)
{
switch (b->type)
{
@@ -13258,7 +13308,8 @@ internal_bkpt_print_mention (struct breakpoint *b)
/* Virtual table for momentary breakpoints */
static void
-momentary_bkpt_re_set (struct breakpoint *b)
+momentary_bkpt_re_set (struct breakpoint *b,
+ struct breakpoint_reset_reason *reason)
{
/* Keep temporary breakpoints, which can be encountered when we step
over a dlopen call and solib_add is resetting the breakpoints.
@@ -13347,6 +13398,7 @@ bkpt_probe_create_sals_from_location (const struct event_location *location,
static void
bkpt_probe_decode_location (struct breakpoint *b,
const struct event_location *location,
+ const struct decode_line_limits *limits,
struct symtabs_and_lines *sals)
{
*sals = parse_probes (location, NULL);
@@ -13357,9 +13409,10 @@ bkpt_probe_decode_location (struct breakpoint *b,
/* The breakpoint_ops structure to be used in tracepoints. */
static void
-tracepoint_re_set (struct breakpoint *b)
+tracepoint_re_set (struct breakpoint *b,
+ struct breakpoint_reset_reason *reason)
{
- breakpoint_re_set_default (b);
+ breakpoint_re_set_default (b, reason);
}
static int
@@ -13471,9 +13524,10 @@ tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
static void
tracepoint_decode_location (struct breakpoint *b,
const struct event_location *location,
+ const struct decode_line_limits *limits,
struct symtabs_and_lines *sals)
{
- decode_location_default (b, location, sals);
+ decode_location_default (b, location, limits, sals);
}
struct breakpoint_ops tracepoint_breakpoint_ops;
@@ -13494,10 +13548,11 @@ tracepoint_probe_create_sals_from_location
static void
tracepoint_probe_decode_location (struct breakpoint *b,
const struct event_location *location,
+ const struct decode_line_limits *limits,
struct symtabs_and_lines *sals)
{
/* We use the same method for breakpoint on probes. */
- bkpt_probe_decode_location (b, location, sals);
+ bkpt_probe_decode_location (b, location, limits, sals);
}
static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
@@ -13505,9 +13560,10 @@ static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
/* Dprintf breakpoint_ops methods. */
static void
-dprintf_re_set (struct breakpoint *b)
+dprintf_re_set (struct breakpoint *b,
+ struct breakpoint_reset_reason *reason)
{
- breakpoint_re_set_default (b);
+ breakpoint_re_set_default (b, reason);
/* extra_string should never be non-NULL for dprintf. */
gdb_assert (b->extra_string != NULL);
@@ -13662,6 +13718,7 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
static void
strace_marker_decode_location (struct breakpoint *b,
const struct event_location *location,
+ const struct decode_line_limits *limits,
struct symtabs_and_lines *sals)
{
struct tracepoint *tp = (struct tracepoint *) b;
@@ -14129,6 +14186,10 @@ update_breakpoint_locations (struct breakpoint *b,
switch_to_program_space_and_thread (sals.sals[i].pspace);
+#if DEBUG_ME
+ printf ("adding location for %s to bp #%d\n",
+ core_addr_to_string (sals.sals[i].pc), b->number);
+#endif
new_loc = add_location_to_breakpoint (b, &(sals.sals[i]));
/* Reparse conditions, they might contain references to the
@@ -14207,12 +14268,18 @@ update_breakpoint_locations (struct breakpoint *b,
update_global_location_list (UGLL_MAY_INSERT);
}
+static int
+no_limits_p (const struct decode_line_limits *limits)
+{
+ return (limits == NULL || limits->objfiles == NULL);
+}
+
/* Find the SaL locations corresponding to the given LOCATION.
On return, FOUND will be 1 if any SaL was found, zero otherwise. */
static struct symtabs_and_lines
location_to_sals (struct breakpoint *b, struct event_location *location,
- int *found)
+ const struct decode_line_limits *limits, int *found)
{
struct symtabs_and_lines sals = {0};
struct gdb_exception exception = exception_none;
@@ -14221,7 +14288,7 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
TRY
{
- b->ops->decode_location (b, location, &sals);
+ b->ops->decode_location (b, location, limits, &sals);
}
CATCH (e, RETURN_MASK_ERROR)
{
@@ -14240,7 +14307,8 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
&& (b->condition_not_parsed
|| (b->loc && b->loc->shlib_disabled)
|| (b->loc && b->loc->pspace->executing_startup)
- || b->enable_state == bp_disabled))
+ || b->enable_state == bp_disabled
+ || !no_limits_p (limits)))
not_found_and_ok = 1;
if (!not_found_and_ok)
@@ -14257,7 +14325,8 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
}
END_CATCH
- if (exception.reason == 0 || exception.error != NOT_FOUND_ERROR)
+ if (exception.reason == 0 || exception.error != NOT_FOUND_ERROR
+ /* KEITHS? && sals.nelts > 0*/)
{
int i;
@@ -14300,31 +14369,60 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
locations. */
static void
-breakpoint_re_set_default (struct breakpoint *b)
+breakpoint_re_set_default (struct breakpoint *b,
+ struct breakpoint_reset_reason *reason)
{
- int found;
+ int found, update;
struct symtabs_and_lines sals, sals_end;
struct symtabs_and_lines expanded = {0};
struct symtabs_and_lines expanded_end = {0};
+ struct decode_line_limits limits;
+
+ /* If there is a reset reason, use that to "limit" SaL lookups. */
+ update = 0;
+ init_decode_line_limits (&limits);
+ switch (reason->reason)
+ {
+ case BREAKPOINT_RESET_ADD_OBJFILE:
+#if 0
+ printf ("ignoring add objfile event\n");
+ return;
+#endif
+ limits.objfiles = reason->objfile_list;
+ break;
+
+ case BREAKPOINT_RESET_NONE:
+ invalidate_linespec_cache (&(b->linespec_cache));
+ /* Always update breakpoint locations in case. */
+ update = 1;
+ break;
- sals = location_to_sals (b, b->location, &found);
+ default:
+ break;
+ }
+
+ sals = location_to_sals (b, b->location, &limits, &found);
if (found)
{
make_cleanup (xfree, sals.sals);
expanded = sals;
+ update = 1;
}
if (b->location_range_end != NULL)
{
- sals_end = location_to_sals (b, b->location_range_end, &found);
+ sals_end = location_to_sals (b, b->location_range_end,
+ &limits, &found);
if (found)
{
make_cleanup (xfree, sals_end.sals);
expanded_end = sals_end;
+ update = 1;
}
}
- update_breakpoint_locations (b, expanded, expanded_end);
+ if (update)
+ update_breakpoint_locations (b, expanded, expanded_end);
}
/* Default method for creating SALs from an address string. It basically
@@ -14368,15 +14466,20 @@ create_breakpoints_sal_default (struct gdbarch *gdbarch,
static void
decode_location_default (struct breakpoint *b,
const struct event_location *location,
+ const struct decode_line_limits *limits,
struct symtabs_and_lines *sals)
{
struct linespec_result canonical;
+ struct decode_line_options opts;
init_linespec_result (&canonical);
- decode_line_full (location, DECODE_LINE_FUNFIRSTLINE,
- (struct symtab *) NULL, 0,
- &canonical, multiple_symbols_all,
- b->filter);
+ init_decode_line_options (&opts);
+ opts.select_mode = multiple_symbols_all;
+ opts.filter = b->filter;
+ opts.limits = limits;
+ opts.cache = b->linespec_cache;
+ opts.flags |= DECODE_LINE_CREATE_CACHE;
+ decode_line_full (location, &canonical, &opts);
/* We should get 0 or 1 resulting SALs. */
gdb_assert (VEC_length (linespec_sals, canonical.sals) < 2);
@@ -14392,6 +14495,8 @@ decode_location_default (struct breakpoint *b,
lsal->sals.sals = NULL;
}
+ b->linespec_cache = canonical.cache;
+ canonical.cache = NULL;
destroy_linespec_result (&canonical);
}
@@ -14411,26 +14516,38 @@ prepare_re_set_context (struct breakpoint *b)
return cleanups;
}
-/* Reset a breakpoint given it's struct breakpoint * BINT.
+/* Reset a breakpoint. DATA contains the information on which breakpoint
+ to reset and why it is being reset.
The value we return ends up being the return value from catch_errors.
Unused in this case. */
static int
-breakpoint_re_set_one (void *bint)
+breakpoint_re_set_one (void *data)
{
/* Get past catch_errs. */
- struct breakpoint *b = (struct breakpoint *) bint;
+ struct breakpoint_re_set_one_info *info
+ = (struct breakpoint_re_set_one_info *) data;
struct cleanup *cleanups;
- cleanups = prepare_re_set_context (b);
- b->ops->re_set (b);
+ cleanups = prepare_re_set_context (info->bp);
+ info->bp->ops->re_set (info->bp, info->reason);
do_cleanups (cleanups);
return 0;
}
+/* Initialize the given reset reason, R. The reason is initialized
+ to BREAKPOINT_RESET_NONE. */
+
+void
+init_breakpoint_reset_reason (struct breakpoint_reset_reason *reason)
+{
+ memset (reason, 0, sizeof (struct breakpoint_reset_reason));
+ reason->reason = BREAKPOINT_RESET_NONE;
+}
+
/* Re-set all breakpoints after symbols have been re-loaded. */
void
-breakpoint_re_set (void)
+breakpoint_re_set (struct breakpoint_reset_reason *reset_reason)
{
struct breakpoint *b, *b_tmp;
enum language save_language;
@@ -14441,15 +14558,38 @@ breakpoint_re_set (void)
save_input_radix = input_radix;
old_chain = save_current_program_space ();
+ /* !!keiths; Add a caller string or some way to identify where
+ the re set came from. */
+ {
+ const char *type;
+
+ switch (reset_reason->reason)
+ {
+ case BREAKPOINT_RESET_ADD_OBJFILE:
+ type = "add objfile";
+ break;
+
+ default:
+ type = "??";
+ };
+
+ //printf ("breakpoint_re_set: %s\n", type);
+ }
+
ALL_BREAKPOINTS_SAFE (b, b_tmp)
{
/* Format possible error msg. */
char *message = xstrprintf ("Error in re-setting breakpoint %d: ",
b->number);
struct cleanup *cleanups = make_cleanup (xfree, message);
- catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
+ struct breakpoint_re_set_one_info info;
+
+ info.bp = b;
+ info.reason = reset_reason;
+ catch_errors (breakpoint_re_set_one, &info, message, RETURN_MASK_ALL);
do_cleanups (cleanups);
}
+ //printf ("breakpoint_re_set done\n");
set_language (save_language);
input_radix = save_input_radix;
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 896d3ebb420..71875d5d9c1 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -26,6 +26,7 @@
#include "command.h"
#include "break-common.h"
#include "probe.h"
+#include "linespec.h"
struct value;
struct block;
@@ -35,9 +36,11 @@ struct get_number_or_range_state;
struct thread_info;
struct bpstats;
struct bp_location;
-struct linespec_result;
+struct linespec;
struct linespec_sals;
struct event_location;
+struct breakpoint_reset_reason;
+struct decode_line_limits;
/* This is the maximum number of bytes a breakpoint instruction can
take. Feel free to increase it. It's just used in a few places to
@@ -508,7 +511,8 @@ struct breakpoint_ops
/* Reevaluate a breakpoint. This is necessary after symbols change
(e.g., an executable or DSO was loaded, or the inferior just
started). */
- void (*re_set) (struct breakpoint *self);
+ void (*re_set) (struct breakpoint *self,
+ struct breakpoint_reset_reason *reason);
/* Insert the breakpoint or watchpoint or activate the catchpoint.
Return 0 for success, 1 if the breakpoint, watchpoint or
@@ -606,6 +610,7 @@ struct breakpoint_ops
This function is called inside `location_to_sals'. */
void (*decode_location) (struct breakpoint *b,
const struct event_location *location,
+ const struct decode_line_limits *,
struct symtabs_and_lines *sals);
/* Return true if this breakpoint explains a signal. See
@@ -679,6 +684,8 @@ struct breakpoint
/* Location(s) associated with this high-level breakpoint. */
struct bp_location *loc;
+ /* !!keiths: cache */
+ struct linespec *linespec_cache;
/* Non-zero means a silent breakpoint (don't print frame info
if we stop here). */
@@ -1198,7 +1205,26 @@ extern void update_breakpoint_locations (struct breakpoint *b,
struct symtabs_and_lines sals,
struct symtabs_and_lines sals_end);
-extern void breakpoint_re_set (void);
+/* Event types that cause breakpoints to re-set. */
+enum breakpoint_reset_type
+{
+ BREAKPOINT_RESET_NONE,
+ BREAKPOINT_RESET_ADD_OBJFILE
+};
+
+struct breakpoint_reset_reason
+{
+ enum breakpoint_reset_type reason;
+ VEC (objfilep) *objfile_list;
+
+ /* for debugging */
+ const char *where;
+};
+
+/* Initialize the given reset reason, R. */
+extern void init_breakpoint_reset_reason (struct breakpoint_reset_reason *r);
+
+extern void breakpoint_re_set (struct breakpoint_reset_reason *r);
extern void breakpoint_re_set_thread (struct breakpoint *);
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 6753c7053db..086bcd922e0 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -807,12 +807,15 @@ edit_command (char *arg, int from_tty)
struct cleanup *cleanup;
struct event_location *location;
char *arg1;
+ struct decode_line_options options;
/* Now should only be one argument -- decode it in SAL. */
+ init_decode_line_options (&options);
+ options.flags = DECODE_LINE_LIST_MODE;
arg1 = arg;
location = string_to_event_location (&arg1, current_language);
cleanup = make_cleanup_delete_event_location (location);
- sals = decode_line_1 (location, DECODE_LINE_LIST_MODE, 0, 0);
+ sals = decode_line_1 (location, &options);
filter_sals (&sals);
if (! sals.nelts)
@@ -963,10 +966,13 @@ list_command (char *arg, int from_tty)
else
{
struct event_location *location;
+ struct decode_line_options options;
location = string_to_event_location (&arg1, current_language);
make_cleanup_delete_event_location (location);
- sals = decode_line_1 (location, DECODE_LINE_LIST_MODE, 0, 0);
+ init_decode_line_options (&options);
+ options.flags = DECODE_LINE_LIST_MODE;
+ sals = decode_line_1 (location, &options);
filter_sals (&sals);
if (!sals.nelts)
@@ -1005,15 +1011,20 @@ list_command (char *arg, int from_tty)
else
{
struct event_location *location;
+ struct decode_line_options options;
location = string_to_event_location (&arg1, current_language);
make_cleanup_delete_event_location (location);
+ init_decode_line_options (&options);
+ options.flags = DECODE_LINE_LIST_MODE;
if (dummy_beg)
- sals_end = decode_line_1 (location,
- DECODE_LINE_LIST_MODE, 0, 0);
+ sals_end = decode_line_1 (location, &options);
else
- sals_end = decode_line_1 (location, DECODE_LINE_LIST_MODE,
- sal.symtab, sal.line);
+ {
+ options.default_symtab = sal.symtab;
+ options.default_line = sal.line;
+ sals_end = decode_line_1 (location, &options);
+ }
filter_sals (&sals_end);
if (sals_end.nelts == 0)
diff --git a/gdb/common/gdb_vecs.h b/gdb/common/gdb_vecs.h
index b3f56f8e0f4..892af1f5677 100644
--- a/gdb/common/gdb_vecs.h
+++ b/gdb/common/gdb_vecs.h
@@ -22,8 +22,10 @@
#include "vec.h"
+struct objfile;
typedef char *char_ptr;
typedef const char *const_char_ptr;
+typedef struct objfile *objfilep;
DEF_VEC_P (char_ptr);
@@ -31,6 +33,8 @@ DEF_VEC_P (const_char_ptr);
DEF_VEC_I (int);
+DEF_VEC_P (objfilep);
+
extern void free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec);
extern struct cleanup *
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 5b123420948..610ddbf7e83 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -74,9 +74,6 @@
#include <fcntl.h>
#include <sys/types.h>
-typedef struct symbol *symbolp;
-DEF_VEC_P (symbolp);
-
/* When == 1, print basic high level tracing messages.
When > 1, be more verbose.
This is in contrast to the low level DIE reading of dwarf_die_debug. */
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 54aa1ef4cc4..be31642459c 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -404,6 +404,7 @@ strip_bg_char (const char *args, int *bg_char_p)
void
post_create_inferior (struct target_ops *target, int from_tty)
{
+ struct breakpoint_reset_reason r;
/* Be sure we own the terminal in case write operations are performed. */
target_terminal_ours ();
@@ -466,7 +467,9 @@ post_create_inferior (struct target_ops *target, int from_tty)
breakpoint_re_set is never called. Call it now so that software
watchpoints get a chance to be promoted to hardware watchpoints
if the now pushed target supports hardware watchpoints. */
- breakpoint_re_set ();
+ init_breakpoint_reset_reason (&r);
+ r.where = __func__;
+ breakpoint_re_set (&r);
observer_notify_inferior_created (target, from_tty);
}
diff --git a/gdb/infrun.c b/gdb/infrun.c
index cf913703197..0b1f451f26f 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -839,6 +839,7 @@ follow_fork (void)
static void
follow_inferior_reset_breakpoints (void)
{
+ struct breakpoint_reset_reason reset_reason;
struct thread_info *tp = inferior_thread ();
/* Was there a step_resume breakpoint? (There was if the user
@@ -872,7 +873,10 @@ follow_inferior_reset_breakpoints (void)
were never set in the child, but only in the parent. This makes
sure the inserted breakpoints match the breakpoint list. */
- breakpoint_re_set ();
+ init_breakpoint_reset_reason (&reset_reason);
+ /*reset_reason.reason = BREAKPOINT_RESET_???;*/
+ reset_reason.where = __func__;
+ breakpoint_re_set (&reset_reason);
insert_breakpoints ();
}
@@ -1096,6 +1100,7 @@ follow_exec (ptid_t ptid, char *execd_pathname)
struct inferior *inf = current_inferior ();
int pid = ptid_get_pid (ptid);
ptid_t process_ptid;
+ struct breakpoint_reset_reason reset_reason;
/* This is an exec event that we actually wish to pay attention to.
Refresh our symbol table to the newly exec'd program, remove any
@@ -1246,11 +1251,29 @@ follow_exec (ptid_t ptid, char *execd_pathname)
registers. */
target_find_description ();
- solib_create_inferior_hook (0);
+ /* Errors on solib_create_inferior_hook are swallowed. In all likelihood,
+ the user has a breakpoint on a user function (like `main') which appears
+ in both the old exec and the new. solib_create_inferior_hook will
+ may call solib_add, which may call update_global_location_list, which
+ may attempt to insert the breakpoints. Since we haven't/can't yet
+ reset all breakpoints, the user's breakpoint may fail to insert.
+ That does not mean, however, that we should just bail. Any real errors
+ resetting/inserting breakpoints will also be triggered when we do reset
+ all the breakpoints, just below. */
+ TRY
+ {
+ solib_create_inferior_hook (0);
+ }
+ CATCH (ex, RETURN_MASK_ERROR)
+ {
+ }
+ END_CATCH
jit_inferior_created_hook ();
- breakpoint_re_set ();
+ init_breakpoint_reset_reason (&reset_reason);
+ reset_reason.where = __func__;
+ breakpoint_re_set (&reset_reason);
/* Reinsert all breakpoints. (Those which were symbolic have
been reset to the proper address in the new a.out, thanks
diff --git a/gdb/linespec.c b/gdb/linespec.c
index b2233b92d8d..f1611b3e9b8 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -45,9 +45,6 @@
#include "stack.h"
#include "location.h"
-typedef struct symbol *symbolp;
-DEF_VEC_P (symbolp);
-
typedef struct type *typep;
DEF_VEC_P (typep);
@@ -61,10 +58,6 @@ struct address_entry
CORE_ADDR addr;
};
-typedef struct bound_minimal_symbol bound_minimal_symbol_d;
-
-DEF_VEC_O (bound_minimal_symbol_d);
-
/* A linespec. Elements of this structure are filled in by a parser
(either parse_linespec or some other function). The structure is
then converted into SALs by convert_linespec_to_sals. */
@@ -148,6 +141,9 @@ struct linespec_state
/* Are we building a linespec? */
int is_linespec;
+
+ /* !!keiths */
+ const struct decode_line_limits *limits;
};
/* This is a helper object that is used when collecting symbols into a
@@ -244,13 +240,17 @@ struct ls_parser
/* Is the entire linespec quote-enclosed? */
int is_quote_enclosed;
+ /* Did RESULT come from a cache? If so, don't free it when the
+ parser is deleted. */
+ int is_cached;
+
/* The state of the parse. */
struct linespec_state state;
#define PARSER_STATE(PPTR) (&(PPTR)->state)
/* The result of the parse. */
- struct linespec result;
-#define PARSER_RESULT(PPTR) (&(PPTR)->result)
+ struct linespec *result;
+#define PARSER_RESULT(PPTR) ((PPTR)->result)
};
typedef struct ls_parser linespec_parser;
@@ -274,7 +274,8 @@ static struct symtabs_and_lines decode_objc (struct linespec_state *self,
linespec_p ls,
const char *arg);
-static VEC (symtab_ptr) *symtabs_from_filename (const char *);
+static VEC (symtab_ptr) *symtabs_from_filename (const char *,
+ VEC (objfilep) *);
static VEC (symbolp) *find_label_symbols (struct linespec_state *self,
VEC (symbolp) *function_symbols,
@@ -302,7 +303,8 @@ static void add_all_symbol_names_from_pspace (struct collect_info *info,
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,
+ VEC (objfilep) *);
static void decode_digits_ordinary (struct linespec_state *self,
linespec_p ls,
@@ -323,6 +325,12 @@ static int compare_symbols (const void *a, const void *b);
static int compare_msymbols (const void *a, const void *b);
+static int classify_mtype (enum minimal_symbol_type t);
+
+#if MERGED_INTO_COMPARE_MSYMBOLS
+static int compare_msyms (const void *a, const void *b);
+#endif
+
/* Permitted quote characters for the parser. This is different from the
completer's quote characters to allow backward compatibility with the
previous parser. */
@@ -962,6 +970,50 @@ iterate_name_matcher (const char *name, void *d)
return 0; /* Skip this symbol. */
}
+#define DEBUG_ME 0
+#define USE_RESET_REASON 1
+
+static void
+do_iterate_over_matching_symtab (struct linespec_state *state,
+ struct objfile *objfile,
+ struct symbol_matcher_data *mdata,
+ const domain_enum domain,
+ symbol_found_callback_ftype callback,
+ void *data, int include_inline)
+{
+ struct compunit_symtab *cu;
+
+ if (objfile->sf)
+ objfile->sf->qf->expand_symtabs_matching (objfile, NULL,
+ iterate_name_matcher,
+ NULL, ALL_DOMAIN,
+ mdata);
+
+ ALL_OBJFILE_COMPUNITS (objfile, cu)
+ {
+ struct symtab *symtab = COMPUNIT_FILETABS (cu);
+
+ iterate_over_file_blocks (symtab, mdata->lookup_name, domain,
+ callback, data);
+
+ if (include_inline)
+ {
+ struct symbol_and_data_callback cad = { callback, data };
+ struct block *block;
+ int i;
+
+ for (i = FIRST_LOCAL_BLOCK;
+ i < BLOCKVECTOR_NBLOCKS (SYMTAB_BLOCKVECTOR (symtab));
+ i++)
+ {
+ block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
+ state->language->la_iterate_over_symbols
+ (block, mdata->lookup_name, domain, iterate_inline_only, &cad);
+ }
+ }
+ }
+}
+
/* A helper that walks over all matching symtabs in all objfiles and
calls CALLBACK for each symbol matching NAME. If SEARCH_PSPACE is
not NULL, then the search is restricted to just that program
@@ -996,39 +1048,38 @@ iterate_over_all_matching_symtabs (struct linespec_state *state,
set_current_program_space (pspace);
- ALL_OBJFILES (objfile)
- {
- struct compunit_symtab *cu;
-
- if (objfile->sf)
- objfile->sf->qf->expand_symtabs_matching (objfile, NULL,
- iterate_name_matcher,
- NULL, ALL_DOMAIN,
- &matcher_data);
+#if USE_RESET_REASON
+ if (state->limits != NULL && state->limits->objfiles != NULL)
+ {
+ int i;
- ALL_OBJFILE_COMPUNITS (objfile, cu)
+ for (i = 0;
+ VEC_iterate (objfilep, state->limits->objfiles, i, objfile);
+ ++i)
+ {
+#if DEBUG_ME
+ printf ("(limit) looking for \"%s\" in objfile %s\n", name,
+ objfile->original_name);
+#endif
+ do_iterate_over_matching_symtab (state, objfile, &matcher_data,
+ domain, callback, data,
+ include_inline);
+ }
+ }
+ else
+#endif
+ {
+ ALL_OBJFILES (objfile)
{
- struct symtab *symtab = COMPUNIT_FILETABS (cu);
-
- iterate_over_file_blocks (symtab, name, domain, callback, data);
-
- if (include_inline)
- {
- struct symbol_and_data_callback cad = { callback, data };
- struct block *block;
- int i;
-
- for (i = FIRST_LOCAL_BLOCK;
- i < BLOCKVECTOR_NBLOCKS (SYMTAB_BLOCKVECTOR (symtab));
- i++)
- {
- block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
- state->language->la_iterate_over_symbols
- (block, name, domain, iterate_inline_only, &cad);
- }
- }
+#if DEBUG_ME
+ printf ("(all) looking for \"%s\" in objfile %s\n", name,
+ objfile->original_name);
+#endif
+ do_iterate_over_matching_symtab (state, objfile, &matcher_data,
+ domain, callback, data,
+ include_inline);
}
- }
+ }
}
}
@@ -1833,6 +1884,7 @@ create_sals_line_offset (struct linespec_state *self,
&& VEC_index (symtab_ptr, ls->file_symtabs, 0) == NULL)
{
const char *fullname;
+ VEC (objfilep) *objfiles = NULL;
set_current_program_space (self->program_space);
@@ -1842,7 +1894,9 @@ create_sals_line_offset (struct linespec_state *self,
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);
+ if (self->limits != NULL)
+ objfiles = self->limits->objfiles;
+ ls->file_symtabs = collect_symtabs_from_filename (fullname, objfiles);
use_default = 1;
}
@@ -2005,7 +2059,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
else if (ls->function_symbols != NULL || ls->minimal_symbols != NULL)
{
/* We have just a bunch of functions and/or methods. */
- int i;
+ int i, classification;
struct symtab_and_line sal;
struct symbol *sym;
bound_minimal_symbol_d *elem;
@@ -2032,16 +2086,26 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
if (ls->minimal_symbols != NULL)
{
- /* Sort minimal symbols by program space, too. */
+ /* Sort minimal symbols by classification and program space. */
qsort (VEC_address (bound_minimal_symbol_d, ls->minimal_symbols),
VEC_length (bound_minimal_symbol_d, ls->minimal_symbols),
sizeof (bound_minimal_symbol_d), compare_msymbols);
+ /* Now the minsyms are in classification order with minsyms
+ of the same program space all adjacent to one another. So,
+ we walk over them and process just the minsyms with the same
+ classification as the very first minsym in the list. */
+ elem = VEC_index (bound_minimal_symbol_d, ls->minimal_symbols, 0);
+ classification = classify_mtype (MSYMBOL_TYPE (elem->minsym));
+
for (i = 0;
VEC_iterate (bound_minimal_symbol_d, ls->minimal_symbols,
i, elem);
++i)
{
+ if (classify_mtype (MSYMBOL_TYPE (elem->minsym))
+ != classification)
+ break;
pspace = elem->objfile->pspace;
set_current_program_space (pspace);
minsym_found (state, elem->objfile, elem->minsym, &sals);
@@ -2088,31 +2152,55 @@ convert_explicit_location_to_sals (struct linespec_state *self,
{
VEC (symbolp) *symbols, *labels;
VEC (bound_minimal_symbol_d) *minimal_symbols;
+ VEC (symtab_ptr) *symtabs = NULL;
if (explicit_loc->source_filename != NULL)
{
TRY
{
- result->file_symtabs
- = symtabs_from_filename (explicit_loc->source_filename);
+ VEC (objfilep) *objfiles = NULL;
+
+ if (self->limits != NULL)
+ objfiles = self->limits->objfiles;
+ symtabs
+ = symtabs_from_filename (explicit_loc->source_filename, objfiles);
}
CATCH (except, RETURN_MASK_ERROR)
{
source_file_not_found_error (explicit_loc->source_filename);
}
END_CATCH
- result->explicit_loc.source_filename
- = xstrdup (explicit_loc->source_filename);
+
+ /* !!keiths: Really what we want to know is if we are doing this
+ incrementally, i.e., there are limits. LIMITS is just about
+ always non-NULL. */
+#define HAS_LIMIT(X) ((X)->limits != NULL && (X)->limits->objfiles != NULL)
+ if (HAS_LIMIT (self))
+ {
+ int ix;
+ struct symtab *elt;
+
+ for (ix = 0; VEC_iterate (symtab_ptr, symtabs, ix, elt); ++ix)
+ VEC_safe_push (symtab_ptr, result->file_symtabs, elt);
+ }
+ else
+ {
+ result->file_symtabs = symtabs;
+ result->explicit_loc.source_filename
+ = xstrdup (explicit_loc->source_filename);
+ }
}
else
{
/* A NULL entry means to use the default symtab. */
- VEC_safe_push (symtab_ptr, result->file_symtabs, NULL);
+ VEC_safe_push (symtab_ptr, symtabs, NULL);
+ if (!HAS_LIMIT (self))
+ result->file_symtabs = symtabs;
}
if (explicit_loc->function_name != NULL)
{
- find_linespec_symbols (self, result->file_symtabs,
+ find_linespec_symbols (self, symtabs,
explicit_loc->function_name, &symbols,
&minimal_symbols);
@@ -2120,28 +2208,62 @@ convert_explicit_location_to_sals (struct linespec_state *self,
symbol_not_found_error (explicit_loc->function_name,
result->explicit_loc.source_filename);
- result->explicit_loc.function_name
- = xstrdup (explicit_loc->function_name);
- result->function_symbols = symbols;
- result->minimal_symbols = minimal_symbols;
+ if (HAS_LIMIT (self))
+ {
+ int ix;
+ bound_minimal_symbol_d *ms_elt;
+ struct symbol *s_elt;
+
+ /* !!keiths: Ick. VEC_merge? */
+ for (ix = 0; VEC_iterate (symbolp, symbols, ix, s_elt); ++ix)
+ VEC_safe_push (symbolp, result->function_symbols, s_elt);
+ for (ix = 0; VEC_iterate (bound_minimal_symbol_d,
+ minimal_symbols, ix, ms_elt); ++ix)
+ {
+ VEC_safe_push (bound_minimal_symbol_d, result->minimal_symbols,
+ ms_elt);
+ }
+ }
+ else
+ {
+ result->explicit_loc.function_name
+ = xstrdup (explicit_loc->function_name);
+ result->function_symbols = symbols;
+ result->minimal_symbols = minimal_symbols;
+ }
}
if (explicit_loc->label_name != NULL)
{
- symbols = NULL;
- labels = find_label_symbols (self, result->function_symbols,
- &symbols, explicit_loc->label_name);
+ VEC (symbolp) *label_symbols = NULL;
+
+ labels = find_label_symbols (self, symbols,
+ &label_symbols, explicit_loc->label_name);
if (labels == NULL)
undefined_label_error (result->explicit_loc.function_name,
explicit_loc->label_name);
- result->explicit_loc.label_name = xstrdup (explicit_loc->label_name);
- result->labels.label_symbols = labels;
- result->labels.function_symbols = symbols;
+ if (HAS_LIMIT (self))
+ {
+ int ix;
+ struct symbol *elt;
+
+ for (ix = 0; VEC_iterate (symbolp, labels, ix, elt); ++ix)
+ VEC_safe_push (symbolp, result->labels.label_symbols, elt);
+ for (ix = 0; VEC_iterate (symbolp, label_symbols, ix, elt); ++ix)
+ VEC_safe_push (symbolp, result->labels.function_symbols, elt);
+ }
+ else
+ {
+ result->explicit_loc.label_name = xstrdup (explicit_loc->label_name);
+ result->labels.label_symbols = labels;
+ result->labels.function_symbols = label_symbols;
+ }
}
- if (explicit_loc->line_offset.sign != LINE_OFFSET_UNKNOWN)
+ if (explicit_loc->line_offset.sign != LINE_OFFSET_UNKNOWN
+ && !HAS_LIMIT (self))
result->explicit_loc.line_offset = explicit_loc->line_offset;
return convert_linespec_to_sals (self, result);
@@ -2284,8 +2406,15 @@ parse_linespec (linespec_parser *parser, const char *arg)
/* Check if the input is a filename. */
TRY
{
+ VEC (objfilep) *objfiles = NULL;
+
+ if (PARSER_STATE (parser)->limits != NULL)
+ objfiles = PARSER_STATE (parser)->limits->objfiles;
+
PARSER_RESULT (parser)->file_symtabs
- = symtabs_from_filename (user_filename);
+ = symtabs_from_filename (user_filename, objfiles);
+ /* !!keiths: From here on out, if file_symtabs does not contain
+ NULL, objfile limits are ALREADY taken into consideration. */
}
CATCH (ex, RETURN_MASK_ERROR)
{
@@ -2366,19 +2495,19 @@ parse_linespec (linespec_parser *parser, const char *arg)
static void
linespec_state_constructor (struct linespec_state *self,
- int flags, const struct language_defn *language,
- struct symtab *default_symtab,
- int default_line,
- struct linespec_result *canonical)
+ const struct language_defn *language,
+ struct linespec_result *canonical,
+ const struct decode_line_options *options)
{
memset (self, 0, sizeof (*self));
self->language = language;
- self->funfirstline = (flags & DECODE_LINE_FUNFIRSTLINE) ? 1 : 0;
- self->list_mode = (flags & DECODE_LINE_LIST_MODE) ? 1 : 0;
- self->default_symtab = default_symtab;
- self->default_line = default_line;
+ self->funfirstline = (options->flags & DECODE_LINE_FUNFIRSTLINE) ? 1 : 0;
+ self->list_mode = (options->flags & DECODE_LINE_LIST_MODE) ? 1 : 0;
+ self->default_symtab = options->default_symtab;
+ self->default_line = options->default_line;
self->canonical = canonical;
self->program_space = current_program_space;
+ self->limits = options->limits;
self->addr_set = htab_create_alloc (10, hash_address_entry, eq_address_entry,
xfree, xcalloc, xfree);
self->is_linespec = 0;
@@ -2388,17 +2517,24 @@ linespec_state_constructor (struct linespec_state *self,
static void
linespec_parser_new (linespec_parser *parser,
- int flags, const struct language_defn *language,
- struct symtab *default_symtab,
- int default_line,
- struct linespec_result *canonical)
+ const struct language_defn *language,
+ struct linespec_result *canonical,
+ const struct decode_line_options *options)
{
memset (parser, 0, sizeof (linespec_parser));
parser->lexer.current.type = LSTOKEN_CONSUMED;
- 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,
- default_symtab, default_line, canonical);
+ if (options->cache == NULL)
+ {
+ PARSER_RESULT (parser) = XCNEW (struct linespec);
+ PARSER_EXPLICIT (parser)->line_offset.sign = LINE_OFFSET_UNKNOWN;
+ }
+ else
+ {
+ PARSER_RESULT (parser) = options->cache;
+ parser->is_cached = 1;
+ }
+ linespec_state_constructor (PARSER_STATE (parser), language,
+ canonical, options);
}
/* A destructor for linespec_state. */
@@ -2409,32 +2545,48 @@ linespec_state_destructor (struct linespec_state *self)
htab_delete (self->addr_set);
}
-/* Delete a linespec parser. */
-
static void
-linespec_parser_delete (void *arg)
+free_linespec_result (linespec_p result)
{
- linespec_parser *parser = (linespec_parser *) arg;
+ if (result == NULL)
+ return;
- xfree (PARSER_EXPLICIT (parser)->source_filename);
- xfree (PARSER_EXPLICIT (parser)->label_name);
- xfree (PARSER_EXPLICIT (parser)->function_name);
+ xfree (result->explicit_loc.source_filename);
+ xfree (result->explicit_loc.label_name);
+ xfree (result->explicit_loc.function_name);
- if (PARSER_RESULT (parser)->file_symtabs != NULL)
- VEC_free (symtab_ptr, PARSER_RESULT (parser)->file_symtabs);
+ if (result->file_symtabs != NULL)
+ VEC_free (symtab_ptr, result->file_symtabs);
- if (PARSER_RESULT (parser)->function_symbols != NULL)
- VEC_free (symbolp, PARSER_RESULT (parser)->function_symbols);
+ if (result->function_symbols != NULL)
+ VEC_free (symbolp, result->function_symbols);
- if (PARSER_RESULT (parser)->minimal_symbols != NULL)
- VEC_free (bound_minimal_symbol_d, PARSER_RESULT (parser)->minimal_symbols);
+ if (result->minimal_symbols != NULL)
+ VEC_free (bound_minimal_symbol_d, result->minimal_symbols);
- if (PARSER_RESULT (parser)->labels.label_symbols != NULL)
- VEC_free (symbolp, PARSER_RESULT (parser)->labels.label_symbols);
+ if (result->labels.label_symbols != NULL)
+ VEC_free (symbolp, result->labels.label_symbols);
+
+ if (result->labels.function_symbols != NULL)
+ VEC_free (symbolp, result->labels.function_symbols);
+}
- if (PARSER_RESULT (parser)->labels.function_symbols != NULL)
- VEC_free (symbolp, PARSER_RESULT (parser)->labels.function_symbols);
+void
+invalidate_linespec_cache (struct linespec **p)
+{
+ free_linespec_result (*p);
+ *p = NULL;
+}
+/* Delete a linespec parser. */
+
+static void
+linespec_parser_delete (void *arg)
+{
+ linespec_parser *parser = (linespec_parser *) arg;
+
+ if (!parser->is_cached)
+ free_linespec_result (PARSER_RESULT (parser));
linespec_state_destructor (PARSER_STATE (parser));
}
@@ -2447,11 +2599,13 @@ linespec_lex_to_end (char **stringp)
struct cleanup *cleanup;
linespec_token token;
const char *orig;
+ struct decode_line_options opts;
if (stringp == NULL || *stringp == NULL)
return;
- linespec_parser_new (&parser, 0, current_language, NULL, 0, NULL);
+ init_decode_line_options (&opts);
+ linespec_parser_new (&parser, current_language, NULL, &opts);
cleanup = make_cleanup (linespec_parser_delete, &parser);
parser.lexer.saved_arg = *stringp;
PARSER_STREAM (&parser) = orig = *stringp;
@@ -2526,38 +2680,56 @@ event_location_to_sals (linespec_parser *parser,
return result;
}
+/* Initialize a decode_line_options structure.
+ OPTS->FLAGS will be initialized to DECODE_LINE_FUNFIRSTLINE. */
+
+void
+init_decode_line_options (struct decode_line_options *opts)
+{
+ memset (opts, 0, sizeof (struct decode_line_options));
+ opts->flags = DECODE_LINE_FUNFIRSTLINE;
+}
+
/* See linespec.h. */
void
-decode_line_full (const struct event_location *location, int flags,
- struct symtab *default_symtab,
- int default_line, struct linespec_result *canonical,
- const char *select_mode,
- const char *filter)
+decode_line_full (const struct event_location *location,
+ struct linespec_result *canonical,
+ const struct decode_line_options *options)
{
struct symtabs_and_lines result;
struct cleanup *cleanups;
VEC (const_char_ptr) *filters = NULL;
linespec_parser parser;
struct linespec_state *state;
+ const char *copy, *orig;
+ const char *select_mode = options->select_mode;
gdb_assert (canonical != NULL);
/* The filter only makes sense for 'all'. */
- gdb_assert (filter == NULL || select_mode == multiple_symbols_all);
+ gdb_assert (options->filter == NULL || select_mode == multiple_symbols_all);
gdb_assert (select_mode == NULL
|| select_mode == multiple_symbols_all
|| select_mode == multiple_symbols_ask
|| select_mode == multiple_symbols_cancel);
- gdb_assert ((flags & DECODE_LINE_LIST_MODE) == 0);
+ gdb_assert ((options->flags & DECODE_LINE_LIST_MODE) == 0);
- linespec_parser_new (&parser, flags, current_language, default_symtab,
- default_line, canonical);
+#if DEBUG_ME
+ if (options->cache != NULL)
+ printf ("*** got linespec cache ***\n");
+#endif
+ linespec_parser_new (&parser, current_language, canonical, options);
cleanups = make_cleanup (linespec_parser_delete, &parser);
save_current_program_space ();
result = event_location_to_sals (&parser, location);
state = PARSER_STATE (&parser);
+ if (options->limits != NULL && result.nelts == 0)
+ {
+ throw_error (NOT_FOUND_ERROR, _("didn't find function under limits"));
+ }
+
gdb_assert (result.nelts == 1 || canonical->pre_expanded);
canonical->pre_expanded = 1;
@@ -2584,10 +2756,10 @@ decode_line_full (const struct event_location *location, int flags,
if (select_mode == multiple_symbols_all)
{
- if (filter != NULL)
+ if (options->filter != NULL)
{
make_cleanup (VEC_cleanup (const_char_ptr), &filters);
- VEC_safe_push (const_char_ptr, filters, filter);
+ VEC_safe_push (const_char_ptr, filters, options->filter);
filter_results (state, &result, filters);
}
else
@@ -2596,22 +2768,31 @@ decode_line_full (const struct event_location *location, int flags,
else
decode_line_2 (state, &result, select_mode);
+ if (options->flags & DECODE_LINE_CREATE_CACHE)
+ {
+#if DEBUG_ME
+ printf ("*** creating linespec cache ***\n");
+#endif
+ canonical->cache = PARSER_RESULT (&parser);
+ /* !!keiths: Hmm. Pretty sure we don't want to be free'ing
+ this when the cleanup is called... */
+ PARSER_RESULT (&parser) = NULL;
+ }
+
do_cleanups (cleanups);
}
/* See linespec.h. */
struct symtabs_and_lines
-decode_line_1 (const struct event_location *location, int flags,
- struct symtab *default_symtab,
- int default_line)
+decode_line_1 (const struct event_location *location,
+ const struct decode_line_options *options)
{
struct symtabs_and_lines result;
linespec_parser parser;
struct cleanup *cleanups;
- linespec_parser_new (&parser, flags, current_language, default_symtab,
- default_line, NULL);
+ linespec_parser_new (&parser, current_language, NULL, options);
cleanups = make_cleanup (linespec_parser_delete, &parser);
save_current_program_space ();
@@ -2630,6 +2811,7 @@ decode_line_with_current_source (char *string, int flags)
struct symtab_and_line cursal;
struct event_location *location;
struct cleanup *cleanup;
+ struct decode_line_options options;
if (string == 0)
error (_("Empty line specification."));
@@ -2640,8 +2822,11 @@ decode_line_with_current_source (char *string, int flags)
location = string_to_event_location (&string, current_language);
cleanup = make_cleanup_delete_event_location (location);
- sals = decode_line_1 (location, flags,
- cursal.symtab, cursal.line);
+ init_decode_line_options (&options);
+ options.flags = flags;
+ options.default_symtab = cursal.symtab;
+ options.default_line = cursal.line;
+ sals = decode_line_1 (location, &options);
if (*string)
error (_("Junk at end of line specification: %s"), string);
@@ -2658,18 +2843,23 @@ decode_line_with_last_displayed (char *string, int flags)
struct symtabs_and_lines sals;
struct event_location *location;
struct cleanup *cleanup;
+ struct decode_line_options options;
if (string == 0)
error (_("Empty line specification."));
location = string_to_event_location (&string, current_language);
cleanup = make_cleanup_delete_event_location (location);
+ init_decode_line_options (&options);
+ options.flags = flags;
if (last_displayed_sal_is_valid ())
- sals = decode_line_1 (location, flags,
- get_last_displayed_symtab (),
- get_last_displayed_line ());
+ {
+ options.default_symtab = get_last_displayed_symtab ();
+ options.default_line = get_last_displayed_line ();
+ sals = decode_line_1 (location, &options);
+ }
else
- sals = decode_line_1 (location, flags, (struct symtab *) NULL, 0);
+ sals = decode_line_1 (location, &options);
if (*string)
error (_("Junk at end of line specification: %s"), string);
@@ -2831,6 +3021,15 @@ collect_one_symbol (struct symbol *sym, void *d)
{
*slot = sym;
VEC_safe_push (symbolp, collector->symbols, sym);
+#if DEBUG_ME
+ {
+ struct objfile *_objfile = SYMBOL_OBJFILE_OWNED (sym) ? symbol_objfile (sym) : NULL;
+
+ printf ("(one) found symbol %s in objfile %s\n",
+ SYMBOL_LINKAGE_NAME (sym),
+ _objfile ? _objfile->original_name : "arch");
+ }
+#endif
}
return 1; /* Continue iterating. */
@@ -2925,7 +3124,15 @@ compare_msymbols (const void *a, const void *b)
const struct bound_minimal_symbol *sb
= (const struct bound_minimal_symbol *) b;
uintptr_t uia, uib;
+ int ca, cb;
+ /* !!keiths: First compare by classification... */
+ ca = classify_mtype (MSYMBOL_TYPE (sa->minsym));
+ cb = classify_mtype (MSYMBOL_TYPE (sb->minsym));
+ if (ca - cb != 0)
+ return ca - cb;
+
+ /* !!keiths; Now compare pspaces. */
uia = (uintptr_t) sa->objfile->pspace;
uib = (uintptr_t) sa->objfile->pspace;
@@ -3120,7 +3327,7 @@ add_symtabs_to_list (struct symtab *symtab, void *d)
/* Given a file name, return a VEC of all matching symtabs. */
static VEC (symtab_ptr) *
-collect_symtabs_from_filename (const char *file)
+collect_symtabs_from_filename (const char *file, VEC (objfilep) *objfiles)
{
struct symtab_collector collector;
struct cleanup *cleanups;
@@ -3138,7 +3345,7 @@ collect_symtabs_from_filename (const char *file)
continue;
set_current_program_space (pspace);
- iterate_over_symtabs (file, add_symtabs_to_list, &collector);
+ iterate_over_symtabs (file, objfiles, add_symtabs_to_list, &collector);
}
do_cleanups (cleanups);
@@ -3148,11 +3355,11 @@ collect_symtabs_from_filename (const char *file)
/* Return all the symtabs associated to the FILENAME. */
static VEC (symtab_ptr) *
-symtabs_from_filename (const char *filename)
+symtabs_from_filename (const char *filename, VEC (objfilep) *objfiles)
{
VEC (symtab_ptr) *result;
- result = collect_symtabs_from_filename (filename);
+ result = collect_symtabs_from_filename (filename, objfiles);
if (VEC_empty (symtab_ptr, result))
{
@@ -3532,7 +3739,18 @@ collect_symbols (struct symbol *sym, void *data)
/* In list mode, add all matching symbols, regardless of class.
This allows the user to type "list a_global_variable". */
if (SYMBOL_CLASS (sym) == LOC_BLOCK || info->state->list_mode)
- VEC_safe_push (symbolp, info->result.symbols, sym);
+ {
+ VEC_safe_push (symbolp, info->result.symbols, sym);
+#if DEBUG_ME
+ {
+ struct objfile *_objfile = SYMBOL_OBJFILE_OWNED (sym) ? symbol_objfile (sym) : NULL;
+
+ printf ("found symbol %s in objfile %s\n",
+ SYMBOL_LINKAGE_NAME (sym),
+ _objfile ? _objfile->original_name : "arch");
+ }
+#endif
+ }
return 1; /* Continue iterating. */
}
@@ -3630,6 +3848,7 @@ classify_mtype (enum minimal_symbol_type t)
}
}
+#if MERGED_INTO_COMPARE_MSYMBOLS
/* Callback for qsort that sorts symbols by priority. */
static int
@@ -3642,6 +3861,7 @@ compare_msyms (const void *a, const void *b)
return classify_mtype (ta) - classify_mtype (tb);
}
+#endif
/* Callback for iterate_over_minimal_symbols that adds the symbol to
the result. */
@@ -3697,6 +3917,10 @@ add_minsym (struct minimal_symbol *minsym, void *d)
}
VEC_safe_push (bound_minimal_symbol_d, info->msyms, &mo);
+#if DEBUG_ME
+ printf ("found minsym %s in objfile %s\n",
+ MSYMBOL_LINKAGE_NAME (minsym), mo.objfile->original_name);
+#endif
}
/* Search for minimal symbols called NAME. If SEARCH_PSPACE
@@ -3736,11 +3960,30 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
set_current_program_space (pspace);
- ALL_OBJFILES (objfile)
- {
- local.objfile = objfile;
- iterate_over_minimal_symbols (objfile, name, add_minsym, &local);
- }
+#if USE_RESET_REASON
+ if (info->state->limits != NULL
+ && info->state->limits->objfiles != NULL)
+ {
+ int i;
+
+ for (i = 0;
+ VEC_iterate (objfilep, info->state->limits->objfiles, i,
+ objfile); ++i)
+ {
+ local.objfile = objfile;
+ iterate_over_minimal_symbols (objfile, name, add_minsym,
+ &local);
+ }
+ }
+ else
+#endif
+ {
+ ALL_OBJFILES (objfile)
+ {
+ local.objfile = objfile;
+ iterate_over_minimal_symbols (objfile, name, add_minsym, &local);
+ }
+ }
}
}
else
@@ -3756,28 +3999,17 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
if (!VEC_empty (bound_minimal_symbol_d, local.msyms))
{
- int classification;
int ix;
bound_minimal_symbol_d *item;
- qsort (VEC_address (bound_minimal_symbol_d, local.msyms),
- VEC_length (bound_minimal_symbol_d, local.msyms),
- sizeof (bound_minimal_symbol_d),
- compare_msyms);
-
- /* Now the minsyms are in classification order. So, we walk
- over them and process just the minsyms with the same
- classification as the very first minsym in the list. */
- item = VEC_index (bound_minimal_symbol_d, local.msyms, 0);
- classification = classify_mtype (MSYMBOL_TYPE (item->minsym));
-
+ /* !!keiths: This pushes ALL minsyms up. This is a small
+ internal API change, but is needed in order to cache the
+ linespec result. Lower priority minsym classes will be
+ filtered when the SaLs are actually created. */
for (ix = 0;
VEC_iterate (bound_minimal_symbol_d, local.msyms, ix, item);
++ix)
{
- if (classify_mtype (MSYMBOL_TYPE (item->minsym)) != classification)
- break;
-
VEC_safe_push (bound_minimal_symbol_d,
info->result.minimal_symbols, item);
}
@@ -3896,6 +4128,7 @@ destroy_linespec_result (struct linespec_result *ls)
xfree (lsal->sals.sals);
}
VEC_free (linespec_sals, ls->sals);
+ free_linespec_result (ls->cache);
}
/* Cleanup function for a linespec_result. */
@@ -3921,3 +4154,9 @@ get_gdb_linespec_parser_quote_characters (void)
{
return linespec_quote_characters;
}
+
+void
+init_decode_line_limits (struct decode_line_limits *limits)
+{
+ memset (limits, 0, sizeof (struct decode_line_limits));
+}
diff --git a/gdb/linespec.h b/gdb/linespec.h
index 2a76283cfc3..83f4e9fbffb 100644
--- a/gdb/linespec.h
+++ b/gdb/linespec.h
@@ -18,8 +18,27 @@
#define LINESPEC_H 1
struct symtab;
+struct bp_location;
+struct symbol;
+struct linespec;
-#include "vec.h"
+#include "gdb_vecs.h"
+
+enum decode_line_limits_op
+ {
+ DECODE_LINE_LIMITS_ADD,
+ DECODE_LINE_LIMITS_REMOVE,
+ DECODE_LINE_LIMITS_INVALIDATE
+ };
+
+struct decode_line_limits
+{
+ enum decode_line_limits_op op;
+ /* !!keiths: union? */
+ VEC (objfilep) *objfiles;
+};
+
+extern void init_decode_line_limits (struct decode_line_limits *);
/* Flags to pass to decode_line_1 and decode_line_full. */
@@ -32,9 +51,38 @@ enum decode_line_flags
/* Set this flag if you want "list mode". In this mode, a
FILE:LINE linespec will always return a result, and such
linespecs will not be expanded to all matches. */
- DECODE_LINE_LIST_MODE = 2
+ DECODE_LINE_LIST_MODE = 2,
+
+ DECODE_LINE_CREATE_CACHE = 4
};
+/* Options for how decode_line_full and decode_line_1 behave.
+ Use init_decode_line_options to initialize it. */
+
+struct decode_line_options
+{
+ /* One of the above decode_line_flags. */
+ int flags;
+
+ /* The default location. If NULL, use the current symtab
+ and line. */
+ struct symtab *default_symtab;
+ int default_line;
+
+ /* One of the multiple_symbols_* constants or NULL, in which case
+ the appropriate CLI value is used. */
+ const char *select_mode;
+
+ /* A string holding a canonical name used for (post-) filtering.
+ If NULL, no filtering is done. Only valid when SELECT_MODE
+ is multiple_symbols_all. */
+ const char *filter;
+
+ /* !!keiths */
+ const struct decode_line_limits *limits;
+ struct linespec *cache;
+};
+
/* decode_line_full returns a vector of these. */
struct linespec_sals
@@ -78,6 +126,9 @@ struct linespec_result
/* The sals. The vector will be freed by
destroy_linespec_result. */
VEC (linespec_sals) *sals;
+
+ /* Cache used to generate the above SaLs. */
+ struct linespec *cache;
};
/* Initialize a linespec_result. */
@@ -93,11 +144,21 @@ extern void destroy_linespec_result (struct linespec_result *);
extern struct cleanup *
make_cleanup_destroy_linespec_result (struct linespec_result *);
-/* Decode a linespec using the provided default symtab and line. */
+/* Invalidate the linespec cache pointed to by P. */
+
+extern void invalidate_linespec_cache (struct linespec **p);
+
+/* Initialize a decode_line_options structure.
+ OPTS->FLAGS will be initialized to DECODE_LINE_FUNFIRSTLINE. */
+
+extern void init_decode_line_options (struct decode_line_options *opts);
+
+/* Decode a linespec using the provided OPTIONS. The only valid
+ members are OPTIONS->default_symtab and OPTIONS->default_line. */
extern struct symtabs_and_lines
- decode_line_1 (const struct event_location *location, int flags,
- struct symtab *default_symtab, int default_line);
+ decode_line_1 (const struct event_location *location,
+ const struct decode_line_options *options);
/* Parse LOCATION and return results. This is the "full"
interface to this module, which handles multiple results
@@ -135,11 +196,9 @@ extern struct symtabs_and_lines
strcmp sense) to FILTER will be returned; all others will be
filtered out. */
-extern void decode_line_full (const struct event_location *location, int flags,
- struct symtab *default_symtab, int default_line,
+extern void decode_line_full (const struct event_location *location,
struct linespec_result *canonical,
- const char *select_mode,
- const char *filter);
+ const struct decode_line_options *options);
/* Given a string, return the line specified by it, using the current
source symtab and line as defaults.
diff --git a/gdb/minsyms.h b/gdb/minsyms.h
index 0b9f0122500..8fdc4eebf79 100644
--- a/gdb/minsyms.h
+++ b/gdb/minsyms.h
@@ -37,6 +37,9 @@ struct bound_minimal_symbol
struct objfile *objfile;
};
+typedef struct bound_minimal_symbol bound_minimal_symbol_d;
+DEF_VEC_O (bound_minimal_symbol_d);
+
/* This header declares most of the API for dealing with minimal
symbols and minimal symbol tables. A few things are declared
elsewhere; see below.
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index d33379f58e0..0ea60f69edc 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -971,7 +971,13 @@ objfile_relocate (struct objfile *objfile,
/* Relocate breakpoints as necessary, after things are relocated. */
if (changed)
- breakpoint_re_set ();
+ {
+ struct breakpoint_reset_reason r;
+
+ init_breakpoint_reset_reason (&r);
+ r.where = __func__;
+ breakpoint_re_set (&r);
+ }
}
/* Rebase (add to the offsets) OBJFILE by SLIDE. SEPARATE_DEBUG_OBJFILE is
@@ -1010,7 +1016,13 @@ objfile_rebase (struct objfile *objfile, CORE_ADDR slide)
/* Relocate breakpoints as necessary, after things are relocated. */
if (changed)
- breakpoint_re_set ();
+ {
+ struct breakpoint_reset_reason r;
+
+ init_breakpoint_reset_reason (&r);
+ r.where = __func__;
+ breakpoint_re_set (&r);
+ }
}
/* Return non-zero if OBJFILE has partial symbols. */
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 1c2d5c600e5..156500ada73 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -748,7 +748,13 @@ gdbpy_decode_line (PyObject *self, PyObject *args)
TRY
{
if (location != NULL)
- sals = decode_line_1 (location, 0, 0, 0);
+ {
+ struct decode_line_options options;
+
+ init_decode_line_options (&options);
+ options.flags = 0;
+ sals = decode_line_1 (location, &options);
+ }
else
{
set_default_source_symtab_and_line ();
diff --git a/gdb/solib.c b/gdb/solib.c
index 9a6e7dee458..4fca34260e0 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -969,6 +969,11 @@ solib_add (const char *pattern, int from_tty,
struct target_ops *target, int readsyms)
{
struct so_list *gdb;
+ struct breakpoint_reset_reason reset_reason;
+
+ init_breakpoint_reset_reason (&reset_reason);
+ reset_reason.reason = BREAKPOINT_RESET_ADD_OBJFILE;
+ reset_reason.where = __func__;
if (print_symbol_loading_p (from_tty, 0, 0))
{
@@ -1025,12 +1030,16 @@ solib_add (const char *pattern, int from_tty,
gdb->so_name);
}
else if (solib_read_symbols (gdb, flags))
- loaded_any_symbols = 1;
+ {
+ VEC_safe_push (objfilep, reset_reason.objfile_list,
+ gdb->objfile);
+ loaded_any_symbols = 1;
+ }
}
}
if (loaded_any_symbols)
- breakpoint_re_set ();
+ breakpoint_re_set (&reset_reason);
if (from_tty && pattern && ! any_matches)
printf_unfiltered
@@ -1423,6 +1432,7 @@ reload_shared_libraries (char *ignored, int from_tty,
struct cmd_list_element *e)
{
const struct target_so_ops *ops;
+ struct breakpoint_reset_reason reset_reason;
reload_shared_libraries_1 (from_tty);
@@ -1460,7 +1470,10 @@ reload_shared_libraries (char *ignored, int from_tty,
solib_add (NULL, 0, NULL, auto_solib_add);
- breakpoint_re_set ();
+ init_breakpoint_reset_reason (&reset_reason);
+ /*reset_reason.reason = BREAKPOINT_RESET_???;*/
+ reset_reason.where = __func__;
+ breakpoint_re_set (&reset_reason);
/* We may have loaded or unloaded debug info for some (or all)
shared libraries. However, frames may still reference them. For
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 682e3cab6dc..5980c65df7c 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1114,7 +1114,13 @@ finish_new_objfile (struct objfile *objfile, int add_flags)
}
else if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
{
- breakpoint_re_set ();
+ struct breakpoint_reset_reason r;
+
+ init_breakpoint_reset_reason (&r);
+ /*r.reason = BREAKPOINT_RESET_???;*/
+ /*VEC_safe_push (objfilep, &(r.objfile_list), objfile);*/
+ r.where = __func__;
+ breakpoint_re_set (&r);
}
/* We're done reading the symbol file; finish off complaints. */
@@ -2072,6 +2078,7 @@ generic_load (const char *args, int from_tty)
struct load_section_data cbdata;
struct load_progress_data total_progress;
struct ui_out *uiout = current_uiout;
+ struct breakpoint_reset_reason reset_reason;
CORE_ADDR entry;
char **argv;
@@ -2154,7 +2161,11 @@ generic_load (const char *args, int from_tty)
breakpoint locations. Loading has changed the contents of that
memory. */
- breakpoint_re_set ();
+ init_breakpoint_reset_reason (&reset_reason);
+ reset_reason.reason = BREAKPOINT_RESET_ADD_OBJFILE;
+ /*VEC_safe_push (objfilep, &(reset_reason.objfile_list), ???); */
+ reset_reason.where = __func__;
+ breakpoint_re_set (&reset_reason);
/* FIXME: are we supposed to call symbol_file_add or not? According
to a comment from remote-mips.c (where a call to symbol_file_add
@@ -2458,10 +2469,6 @@ remove_symbol_file_command (char *args, int from_tty)
do_cleanups (my_cleanups);
}
-typedef struct objfile *objfilep;
-
-DEF_VEC_P (objfilep);
-
/* Re-read symbols if a symbol-file has changed. */
void
@@ -3022,7 +3029,14 @@ clear_symtab_users (int add_flags)
/* Now that the various caches have been cleared, we can re_set
our breakpoints without risking it using stale data. */
if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
- breakpoint_re_set ();
+ {
+ struct breakpoint_reset_reason r;
+
+ init_breakpoint_reset_reason (&r);
+ /*r.reason = BREAKPOINT_RESET_???;*/
+ r.where = __func__;
+ breakpoint_re_set (&r);
+ }
}
static void
diff --git a/gdb/symtab.c b/gdb/symtab.c
index c95b651f69a..f0255b67375 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -416,11 +416,16 @@ iterate_over_some_symtabs (const char *name,
psymtabs. *If* there is no '/' in the name, a match after a '/'
in the symtab filename will also work.
+ If OBJFILES is NULL, iterate over all objfiles; otherwise, limit
+ the search to those listed in OBJFILES.
+
Calls CALLBACK with each symtab that is found and with the supplied
DATA. If CALLBACK returns true, the search stops. */
+#define DEBUG_ME 0
+
void
-iterate_over_symtabs (const char *name,
+iterate_over_symtabs (const char *name, VEC (objfilep) *objfiles,
int (*callback) (struct symtab *symtab,
void *data),
void *data)
@@ -438,32 +443,117 @@ iterate_over_symtabs (const char *name,
gdb_assert (IS_ABSOLUTE_PATH (real_path));
}
- ALL_OBJFILES (objfile)
- {
- if (iterate_over_some_symtabs (name, real_path, callback, data,
- objfile->compunit_symtabs, NULL))
+ if (objfiles == NULL)
+ {
+ ALL_OBJFILES (objfile)
{
- do_cleanups (cleanups);
- return;
+#if DEBUG_ME
+ printf ("(all) looking for '%s' symtabs in %s ... ", name,
+ objfile->original_name);
+#endif
+ if (iterate_over_some_symtabs (name, real_path, callback, data,
+ objfile->compunit_symtabs, NULL))
+ {
+#if DEBUG_ME
+ printf ("*** found ***\n");
+#endif
+ do_cleanups (cleanups);
+ return;
+ }
+#if DEBUG_ME
+ else
+ printf ("not found\n");
+#endif
}
- }
+ }
+ else
+ {
+ int i;
+ struct objfile *elt;
+
+ for (i = 0; VEC_iterate (objfilep, objfiles, i, elt); ++i)
+ {
+#if DEBUG_ME
+ printf ("(limit) looking for '%s' symtabs in %s ... ", name,
+ elt->original_name);
+#endif
+ if (iterate_over_some_symtabs (name, real_path, callback,
+ data, elt->compunit_symtabs, NULL))
+ {
+#if DEBUG_ME
+ printf ("found\n");
+#endif
+ do_cleanups (cleanups);
+ return;
+ }
+#if DEBUG_ME
+ else
+ printf ("not found\n");
+#endif
+ }
+ }
/* Same search rules as above apply here, but now we look thru the
psymtabs. */
- ALL_OBJFILES (objfile)
- {
- if (objfile->sf
- && objfile->sf->qf->map_symtabs_matching_filename (objfile,
- name,
- real_path,
- callback,
- data))
+ if (objfiles == NULL)
+ {
+ ALL_OBJFILES (objfile)
{
- do_cleanups (cleanups);
- return;
+#if DEBUG_ME
+ printf ("(all) looking for '%s' psymtabs in %s ... ", name,
+ objfile->original_name);
+#endif
+ if (objfile->sf
+ && objfile->sf->qf->map_symtabs_matching_filename (objfile,
+ name,
+ real_path,
+ callback,
+ data))
+ {
+#if DEBUG_ME
+ printf ("found\n");
+#endif
+ do_cleanups (cleanups);
+ return;
+ }
+#if DEBUG_ME
+ else
+ printf ("not found\n");
+#endif
+
}
- }
+ }
+ else
+ {
+ int i;
+ struct objfile *elt;
+
+ for (i = 0; VEC_iterate (objfilep, objfiles, i, elt); ++i)
+ {
+#if DEBUG_ME
+ printf ("(limit) looking for '%s' psymtabs in %s ... ", name,
+ elt->original_name);
+#endif
+ if (elt->sf != NULL
+ && elt->sf->qf->map_symtabs_matching_filename (elt,
+ name,
+ real_path,
+ callback,
+ data))
+ {
+#if DEBUG_ME
+ printf ("found\n");
+#endif
+ do_cleanups (cleanups);
+ return;
+ }
+#if DEBUG_ME
+ else
+ printf ("not found\n");
+#endif
+ }
+ }
do_cleanups (cleanups);
}
@@ -487,7 +577,7 @@ lookup_symtab (const char *name)
{
struct symtab *result = NULL;
- iterate_over_symtabs (name, lookup_symtab_callback, &result);
+ iterate_over_symtabs (name, NULL, lookup_symtab_callback, &result);
return result;
}
diff --git a/gdb/symtab.h b/gdb/symtab.h
index d3f6370666b..86fcf394547 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -816,6 +816,9 @@ struct symbol
struct symbol *hash_next;
};
+typedef struct symbol *symbolp;
+DEF_VEC_P (symbolp);
+
/* Several lookup functions return both a symbol and the block in which the
symbol is found. This structure is used in these cases. */
@@ -1603,6 +1606,7 @@ int iterate_over_some_symtabs (const char *name,
struct compunit_symtab *after_last);
void iterate_over_symtabs (const char *name,
+ VEC (objfilep) *objfiles,
int (*callback) (struct symtab *symtab,
void *data),
void *data);
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 6ca66e7c8d1..9ff61e3cc9f 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -2713,6 +2713,7 @@ scope_info (char *args, int from_tty)
int regno;
struct event_location *location;
struct cleanup *back_to;
+ struct decode_line_options options;
if (args == 0 || *args == 0)
error (_("requires an argument (function, "
@@ -2720,7 +2721,8 @@ scope_info (char *args, int from_tty)
location = string_to_event_location (&args, current_language);
back_to = make_cleanup_delete_event_location (location);
- sals = decode_line_1 (location, DECODE_LINE_FUNFIRSTLINE, NULL, 0);
+ init_decode_line_options (&options);
+ sals = decode_line_1 (location, &options);
if (sals.nelts == 0)
{
/* Presumably decode_line_1 has already warned. */