summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsergiodj <sergiodj>2012-01-16 17:44:32 +0000
committersergiodj <sergiodj>2012-01-16 17:44:32 +0000
commitc9ea08b938e6c8804cfe952f7a33c6739d3e3141 (patch)
tree4f16b573348f7cddeafff9ceba409939906d5e35
parent35dec6ed88864cef7864cad0b83d7b3299598da8 (diff)
downloadgdb-c9ea08b938e6c8804cfe952f7a33c6739d3e3141.tar.gz
2012-01-16 Sergio Durigan Junior <sergiodj@redhat.com>
* breakpoint.c (create_sals_from_address_default): New function. (create_breakpoints_sal_default): Likewise. (decode_linespec_default): Likewise. (is_marker_spec): Removed. (strace_marker_p): New function. (init_breakpoint_sal): Using `strace_marker_p' instead of `is_marker_spec'. (create_breakpoint): Call method `create_sals_from_address' from breakpoint_ops, replacing code that created SALs conditionally on the type of the breakpoint. Call method `create_breakpoints_sal', replacing code that created breakpoints conditionally on the type wanted. (base_breakpoint_create_sals_from_address): New function. (base_breakpoint_create_breakpoints_sal): Likewise. (base_breakpoint_decode_linespec): Likewise. (base_breakpoint_ops): Add methods `base_breakpoint_create_sals_from_address', `base_breakpoint_create_breakpoints_sal' and `base_breakpoint_decode_linespec'. (bkpt_create_sals_from_address): New function. (bkpt_create_breakpoints_sal): Likewise. (bkpt_decode_linespec): Likewise. (tracepoint_create_sals_from_address): Likewise. (tracepoint_create_breakpoints_sal): Likewise. (tracepoint_decode_linespec): Likewise. (strace_marker_create_sals_from_address): Likewise. (strace_marker_create_breakpoints_sal): Likewise. (strace_marker_decode_linespec): Likewise. (strace_marker_breakpoint_ops): New variable. (addr_string_to_sals): Remove `marker_spec'. Call method `decode_linespec' from breakpoint_ops, replacing code that decoded an address string into a SAL. Use `strace_marker_p' instead of `marker_spec'. (strace_command): Decide whether we are dealing with a static tracepoint with marker or not. Use the appropriate breakpoint_ops. (initialize_breakpoint_ops): Initialize new fields of breakpoint_ops. * breakpoint.h (linespec_result, linespec_sals): New forward declarations. (breakpoint_ops) <create_sals_from_address>, <create_breakpoints_sal>, <decode_linespec>: New methods.
-rw-r--r--gdb/ChangeLog43
-rw-r--r--gdb/breakpoint.c455
-rw-r--r--gdb/breakpoint.h33
3 files changed, 411 insertions, 120 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 507ede4deaa..70fba10ef6d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,46 @@
+2012-01-16 Sergio Durigan Junior <sergiodj@redhat.com>
+
+ * breakpoint.c (create_sals_from_address_default): New function.
+ (create_breakpoints_sal_default): Likewise.
+ (decode_linespec_default): Likewise.
+ (is_marker_spec): Removed.
+ (strace_marker_p): New function.
+ (init_breakpoint_sal): Using `strace_marker_p' instead of
+ `is_marker_spec'.
+ (create_breakpoint): Call method `create_sals_from_address' from
+ breakpoint_ops, replacing code that created SALs conditionally
+ on the type of the breakpoint. Call method `create_breakpoints_sal',
+ replacing code that created breakpoints conditionally on the type
+ wanted.
+ (base_breakpoint_create_sals_from_address): New function.
+ (base_breakpoint_create_breakpoints_sal): Likewise.
+ (base_breakpoint_decode_linespec): Likewise.
+ (base_breakpoint_ops): Add methods
+ `base_breakpoint_create_sals_from_address',
+ `base_breakpoint_create_breakpoints_sal' and
+ `base_breakpoint_decode_linespec'.
+ (bkpt_create_sals_from_address): New function.
+ (bkpt_create_breakpoints_sal): Likewise.
+ (bkpt_decode_linespec): Likewise.
+ (tracepoint_create_sals_from_address): Likewise.
+ (tracepoint_create_breakpoints_sal): Likewise.
+ (tracepoint_decode_linespec): Likewise.
+ (strace_marker_create_sals_from_address): Likewise.
+ (strace_marker_create_breakpoints_sal): Likewise.
+ (strace_marker_decode_linespec): Likewise.
+ (strace_marker_breakpoint_ops): New variable.
+ (addr_string_to_sals): Remove `marker_spec'. Call method
+ `decode_linespec' from breakpoint_ops, replacing code that decoded
+ an address string into a SAL. Use `strace_marker_p' instead of
+ `marker_spec'.
+ (strace_command): Decide whether we are dealing with a static
+ tracepoint with marker or not. Use the appropriate breakpoint_ops.
+ (initialize_breakpoint_ops): Initialize new fields of breakpoint_ops.
+ * breakpoint.h (linespec_result, linespec_sals): New forward
+ declarations.
+ (breakpoint_ops) <create_sals_from_address>,
+ <create_breakpoints_sal>, <decode_linespec>: New methods.
+
2012-01-14 Doug Evans <dje@google.com>
* NEWS: Update text for "maint set python print-stack".
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 88fc176f675..e9d29ff6b41 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -96,6 +96,23 @@ static int breakpoint_re_set_one (void *);
static void breakpoint_re_set_default (struct breakpoint *);
+static void create_sals_from_address_default (char **,
+ struct linespec_result *,
+ enum bptype, char *,
+ char **);
+
+static void create_breakpoints_sal_default (struct gdbarch *,
+ struct linespec_result *,
+ struct linespec_sals *,
+ char *, enum bptype,
+ enum bpdisp, int, int,
+ int,
+ const struct breakpoint_ops *,
+ int, int, int);
+
+static void decode_linespec_default (struct breakpoint *, char **,
+ struct symtabs_and_lines *);
+
static void clear_command (char *, int);
static void catch_command (char *, int);
@@ -237,10 +254,10 @@ static void trace_pass_command (char *, int);
static int is_masked_watchpoint (const struct breakpoint *b);
-/* Assuming we're creating a static tracepoint, does S look like a
- static tracepoint marker spec ("-m MARKER_ID")? */
-#define is_marker_spec(s) \
- (s != NULL && strncmp (s, "-m", 2) == 0 && ((s)[2] == ' ' || (s)[2] == '\t'))
+/* Return 1 if B refers to a static tracepoint set by marker ("-m"), zero
+ otherwise. */
+
+static int strace_marker_p (struct breakpoint *b);
/* The abstract base class all breakpoint_ops structures inherit
from. */
@@ -7298,7 +7315,7 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
struct tracepoint *t = (struct tracepoint *) b;
struct static_tracepoint_marker marker;
- if (is_marker_spec (addr_string))
+ if (strace_marker_p (b))
{
/* We already know the marker exists, otherwise, we
wouldn't see a sal for it. */
@@ -7720,32 +7737,19 @@ create_breakpoint (struct gdbarch *gdbarch,
init_linespec_result (&canonical);
- if (type_wanted == bp_static_tracepoint && is_marker_spec (arg))
- {
- int i;
- struct linespec_sals lsal;
-
- lsal.sals = decode_static_tracepoint_spec (&arg);
-
- copy_arg = savestring (addr_start, arg - addr_start);
-
- canonical.addr_string = xstrdup (copy_arg);
- lsal.canonical = xstrdup (copy_arg);
- VEC_safe_push (linespec_sals, canonical.sals, &lsal);
-
- goto done;
- }
-
TRY_CATCH (e, RETURN_MASK_ALL)
{
- parse_breakpoint_sals (&arg, &canonical);
+ ops->create_sals_from_address (&arg, &canonical, type_wanted,
+ addr_start, &copy_arg);
}
/* If caller is interested in rc value from parse, set value. */
switch (e.reason)
{
- case RETURN_QUIT:
- throw_exception (e);
+ case GDB_NO_ERROR:
+ if (VEC_empty (linespec_sals, canonical.sals))
+ return 0;
+ break;
case RETURN_ERROR:
switch (e.error)
{
@@ -7787,12 +7791,9 @@ create_breakpoint (struct gdbarch *gdbarch,
}
break;
default:
- if (VEC_empty (linespec_sals, canonical.sals))
- return 0;
+ throw_exception (e);
}
- done:
-
/* Create a chain of things that always need to be cleaned up. */
old_chain = make_cleanup_destroy_linespec_result (&canonical);
@@ -7855,57 +7856,11 @@ create_breakpoint (struct gdbarch *gdbarch,
}
}
- /* If the user is creating a static tracepoint by marker id
- (strace -m MARKER_ID), then store the sals index, so that
- breakpoint_re_set can try to match up which of the newly
- found markers corresponds to this one, and, don't try to
- expand multiple locations for each sal, given than SALS
- already should contain all sals for MARKER_ID. */
- if (type_wanted == bp_static_tracepoint
- && is_marker_spec (copy_arg))
- {
- int i;
-
- for (i = 0; i < lsal->sals.nelts; ++i)
- {
- struct symtabs_and_lines expanded;
- struct tracepoint *tp;
- struct cleanup *old_chain;
- char *addr_string;
-
- expanded.nelts = 1;
- expanded.sals = &lsal->sals.sals[i];
-
- addr_string = xstrdup (canonical.addr_string);
- old_chain = make_cleanup (xfree, addr_string);
-
- tp = XCNEW (struct tracepoint);
- init_breakpoint_sal (&tp->base, gdbarch, expanded,
- addr_string, NULL,
+ ops->create_breakpoints_sal (gdbarch, &canonical, lsal,
cond_string, type_wanted,
tempflag ? disp_del : disp_donttouch,
thread, task, ignore_count, ops,
- from_tty, enabled, internal,
- canonical.special_display);
- /* Given that its possible to have multiple markers with
- the same string id, if the user is creating a static
- tracepoint by marker id ("strace -m MARKER_ID"), then
- store the sals index, so that breakpoint_re_set can
- try to match up which of the newly found markers
- corresponds to this one */
- tp->static_trace_marker_id_idx = i;
-
- install_breakpoint (internal, &tp->base, 0);
-
- discard_cleanups (old_chain);
- }
- }
- else
- create_breakpoints_sal (gdbarch, &canonical, cond_string,
- type_wanted,
- tempflag ? disp_del : disp_donttouch,
- thread, task, ignore_count, ops, from_tty,
- enabled, internal);
+ from_tty, enabled, internal);
}
else
{
@@ -10910,6 +10865,39 @@ base_breakpoint_print_recreate (struct breakpoint *b, struct ui_file *fp)
internal_error_pure_virtual_called ();
}
+static void
+base_breakpoint_create_sals_from_address (char **arg,
+ struct linespec_result *canonical,
+ enum bptype type_wanted,
+ char *addr_start,
+ char **copy_arg)
+{
+ internal_error_pure_virtual_called ();
+}
+
+static void
+base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
+ struct linespec_result *c,
+ struct linespec_sals *lsal,
+ char *cond_string,
+ enum bptype type_wanted,
+ enum bpdisp disposition,
+ int thread,
+ int task, int ignore_count,
+ const struct breakpoint_ops *o,
+ int from_tty, int enabled,
+ int internal)
+{
+ internal_error_pure_virtual_called ();
+}
+
+static void
+base_breakpoint_decode_linespec (struct breakpoint *b, char **s,
+ struct symtabs_and_lines *sals)
+{
+ internal_error_pure_virtual_called ();
+}
+
static struct breakpoint_ops base_breakpoint_ops =
{
base_breakpoint_dtor,
@@ -10925,7 +10913,10 @@ static struct breakpoint_ops base_breakpoint_ops =
NULL,
base_breakpoint_print_one_detail,
base_breakpoint_print_mention,
- base_breakpoint_print_recreate
+ base_breakpoint_print_recreate,
+ base_breakpoint_create_sals_from_address,
+ base_breakpoint_create_breakpoints_sal,
+ base_breakpoint_decode_linespec,
};
/* Default breakpoint_ops methods. */
@@ -11071,6 +11062,43 @@ bkpt_print_recreate (struct breakpoint *tp, struct ui_file *fp)
print_recreate_thread (tp, fp);
}
+static void
+bkpt_create_sals_from_address (char **arg,
+ struct linespec_result *canonical,
+ enum bptype type_wanted,
+ char *addr_start, char **copy_arg)
+{
+ create_sals_from_address_default (arg, canonical, type_wanted,
+ addr_start, copy_arg);
+}
+
+static void
+bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
+ struct linespec_result *canonical,
+ struct linespec_sals *lsal,
+ char *cond_string,
+ enum bptype type_wanted,
+ enum bpdisp disposition,
+ int thread,
+ int task, int ignore_count,
+ const struct breakpoint_ops *ops,
+ int from_tty, int enabled,
+ int internal)
+{
+ create_breakpoints_sal_default (gdbarch, canonical, lsal,
+ cond_string, type_wanted,
+ disposition, thread, task,
+ ignore_count, ops, from_tty,
+ enabled, internal);
+}
+
+static void
+bkpt_decode_linespec (struct breakpoint *b, char **s,
+ struct symtabs_and_lines *sals)
+{
+ decode_linespec_default (b, s, sals);
+}
+
/* Virtual table for internal breakpoints. */
static void
@@ -11297,8 +11325,145 @@ tracepoint_print_recreate (struct breakpoint *self, struct ui_file *fp)
fprintf_unfiltered (fp, " passcount %d\n", tp->pass_count);
}
+static void
+tracepoint_create_sals_from_address (char **arg,
+ struct linespec_result *canonical,
+ enum bptype type_wanted,
+ char *addr_start, char **copy_arg)
+{
+ create_sals_from_address_default (arg, canonical, type_wanted,
+ addr_start, copy_arg);
+}
+
+static void
+tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
+ struct linespec_result *canonical,
+ struct linespec_sals *lsal,
+ char *cond_string,
+ enum bptype type_wanted,
+ enum bpdisp disposition,
+ int thread,
+ int task, int ignore_count,
+ const struct breakpoint_ops *ops,
+ int from_tty, int enabled,
+ int internal)
+{
+ create_breakpoints_sal_default (gdbarch, canonical, lsal,
+ cond_string, type_wanted,
+ disposition, thread, task,
+ ignore_count, ops, from_tty,
+ enabled, internal);
+}
+
+static void
+tracepoint_decode_linespec (struct breakpoint *b, char **s,
+ struct symtabs_and_lines *sals)
+{
+ decode_linespec_default (b, s, sals);
+}
+
struct breakpoint_ops tracepoint_breakpoint_ops;
+/* The breakpoint_ops structure to be used on static tracepoints with
+ markers (`-m'). */
+
+static void
+strace_marker_create_sals_from_address (char **arg,
+ struct linespec_result *canonical,
+ enum bptype type_wanted,
+ char *addr_start, char **copy_arg)
+{
+ struct linespec_sals lsal;
+
+ lsal.sals = decode_static_tracepoint_spec (arg);
+
+ *copy_arg = savestring (addr_start, *arg - addr_start);
+
+ canonical->addr_string = xstrdup (*copy_arg);
+ lsal.canonical = xstrdup (*copy_arg);
+ VEC_safe_push (linespec_sals, canonical->sals, &lsal);
+}
+
+static void
+strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
+ struct linespec_result *canonical,
+ struct linespec_sals *lsal,
+ char *cond_string,
+ enum bptype type_wanted,
+ enum bpdisp disposition,
+ int thread,
+ int task, int ignore_count,
+ const struct breakpoint_ops *ops,
+ int from_tty, int enabled,
+ int internal)
+{
+ int i;
+
+ /* If the user is creating a static tracepoint by marker id
+ (strace -m MARKER_ID), then store the sals index, so that
+ breakpoint_re_set can try to match up which of the newly
+ found markers corresponds to this one, and, don't try to
+ expand multiple locations for each sal, given than SALS
+ already should contain all sals for MARKER_ID. */
+
+ for (i = 0; i < lsal->sals.nelts; ++i)
+ {
+ struct symtabs_and_lines expanded;
+ struct tracepoint *tp;
+ struct cleanup *old_chain;
+ char *addr_string;
+
+ expanded.nelts = 1;
+ expanded.sals = &lsal->sals.sals[i];
+
+ addr_string = xstrdup (canonical->addr_string);
+ old_chain = make_cleanup (xfree, addr_string);
+
+ tp = XCNEW (struct tracepoint);
+ init_breakpoint_sal (&tp->base, gdbarch, expanded,
+ addr_string, NULL,
+ cond_string, type_wanted, disposition,
+ thread, task, ignore_count, ops,
+ from_tty, enabled, internal,
+ canonical->special_display);
+ /* Given that its possible to have multiple markers with
+ the same string id, if the user is creating a static
+ tracepoint by marker id ("strace -m MARKER_ID"), then
+ store the sals index, so that breakpoint_re_set can
+ try to match up which of the newly found markers
+ corresponds to this one */
+ tp->static_trace_marker_id_idx = i;
+
+ install_breakpoint (internal, &tp->base, 0);
+
+ discard_cleanups (old_chain);
+ }
+}
+
+static void
+strace_marker_decode_linespec (struct breakpoint *b, char **s,
+ struct symtabs_and_lines *sals)
+{
+ struct tracepoint *tp = (struct tracepoint *) b;
+
+ *sals = decode_static_tracepoint_spec (s);
+ if (sals->nelts > tp->static_trace_marker_id_idx)
+ {
+ sals->sals[0] = sals->sals[tp->static_trace_marker_id_idx];
+ sals->nelts = 1;
+ }
+ else
+ error (_("marker %s not found"), tp->static_trace_marker_id);
+}
+
+static struct breakpoint_ops strace_marker_breakpoint_ops;
+
+static int
+strace_marker_p (struct breakpoint *b)
+{
+ return b->ops == &strace_marker_breakpoint_ops;
+}
+
/* Delete a breakpoint and clean up all traces of it in the data
structures. */
@@ -11833,54 +11998,15 @@ static struct symtabs_and_lines
addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
{
char *s;
- int marker_spec;
struct symtabs_and_lines sals = {0};
volatile struct gdb_exception e;
+ gdb_assert (b->ops != NULL);
s = addr_string;
- marker_spec = b->type == bp_static_tracepoint && is_marker_spec (s);
TRY_CATCH (e, RETURN_MASK_ERROR)
{
- if (marker_spec)
- {
- struct tracepoint *tp = (struct tracepoint *) b;
-
- sals = decode_static_tracepoint_spec (&s);
- if (sals.nelts > tp->static_trace_marker_id_idx)
- {
- sals.sals[0] = sals.sals[tp->static_trace_marker_id_idx];
- sals.nelts = 1;
- }
- else
- error (_("marker %s not found"), tp->static_trace_marker_id);
- }
- else
- {
- struct linespec_result canonical;
-
- init_linespec_result (&canonical);
- decode_line_full (&s, DECODE_LINE_FUNFIRSTLINE,
- (struct symtab *) NULL, 0,
- &canonical, multiple_symbols_all,
- b->filter);
-
- /* We should get 0 or 1 resulting SALs. */
- gdb_assert (VEC_length (linespec_sals, canonical.sals) < 2);
-
- if (VEC_length (linespec_sals, canonical.sals) > 0)
- {
- struct linespec_sals *lsal;
-
- lsal = VEC_index (linespec_sals, canonical.sals, 0);
- sals = lsal->sals;
- /* Arrange it so the destructor does not free the
- contents. */
- lsal->sals.sals = NULL;
- }
-
- destroy_linespec_result (&canonical);
- }
+ b->ops->decode_linespec (b, &s, &sals);
}
if (e.reason < 0)
{
@@ -11933,7 +12059,7 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
b->condition_not_parsed = 0;
}
- if (b->type == bp_static_tracepoint && !marker_spec)
+ if (b->type == bp_static_tracepoint && !strace_marker_p (b))
sals.sals[0] = update_static_tracepoint (b, sals.sals[0]);
*found = 1;
@@ -11976,6 +12102,73 @@ breakpoint_re_set_default (struct breakpoint *b)
update_breakpoint_locations (b, expanded, expanded_end);
}
+/* Default method for creating SALs from an address string. It basically
+ calls parse_breakpoint_sals. Return 1 for success, zero for failure. */
+
+static void
+create_sals_from_address_default (char **arg,
+ struct linespec_result *canonical,
+ enum bptype type_wanted,
+ char *addr_start, char **copy_arg)
+{
+ parse_breakpoint_sals (arg, canonical);
+}
+
+/* Call create_breakpoints_sal for the given arguments. This is the default
+ function for the `create_breakpoints_sal' method of
+ breakpoint_ops. */
+
+static void
+create_breakpoints_sal_default (struct gdbarch *gdbarch,
+ struct linespec_result *canonical,
+ struct linespec_sals *lsal,
+ char *cond_string,
+ enum bptype type_wanted,
+ enum bpdisp disposition,
+ int thread,
+ int task, int ignore_count,
+ const struct breakpoint_ops *ops,
+ int from_tty, int enabled,
+ int internal)
+{
+ create_breakpoints_sal (gdbarch, canonical, cond_string,
+ type_wanted, disposition,
+ thread, task, ignore_count, ops, from_tty,
+ enabled, internal);
+}
+
+/* Decode the line represented by S by calling decode_line_full. This is the
+ default function for the `decode_linespec' method of breakpoint_ops. */
+
+static void
+decode_linespec_default (struct breakpoint *b, char **s,
+ struct symtabs_and_lines *sals)
+{
+ struct linespec_result canonical;
+
+ init_linespec_result (&canonical);
+ decode_line_full (s, DECODE_LINE_FUNFIRSTLINE,
+ (struct symtab *) NULL, 0,
+ &canonical, multiple_symbols_all,
+ b->filter);
+
+ /* We should get 0 or 1 resulting SALs. */
+ gdb_assert (VEC_length (linespec_sals, canonical.sals) < 2);
+
+ if (VEC_length (linespec_sals, canonical.sals) > 0)
+ {
+ struct linespec_sals *lsal;
+
+ lsal = VEC_index (linespec_sals, canonical.sals, 0);
+ *sals = lsal->sals;
+ /* Arrange it so the destructor does not free the
+ contents. */
+ lsal->sals.sals = NULL;
+ }
+
+ destroy_linespec_result (&canonical);
+}
+
/* Prepare the global context for a re-set of breakpoint B. */
static struct cleanup *
@@ -12794,6 +12987,15 @@ ftrace_command (char *arg, int from_tty)
void
strace_command (char *arg, int from_tty)
{
+ struct breakpoint_ops *ops;
+
+ /* Decide if we are dealing with a static tracepoint marker (`-m'),
+ or with a normal static tracepoint. */
+ if (arg && strncmp (arg, "-m", 2) == 0 && isspace (arg[2]))
+ ops = &strace_marker_breakpoint_ops;
+ else
+ ops = &tracepoint_breakpoint_ops;
+
if (create_breakpoint (get_current_arch (),
arg,
NULL, 0, 1 /* parse arg */,
@@ -12801,7 +13003,7 @@ strace_command (char *arg, int from_tty)
bp_static_tracepoint /* type_wanted */,
0 /* Ignore count */,
pending_break_support,
- &tracepoint_breakpoint_ops,
+ ops,
from_tty,
1 /* enabled */,
0 /* internal */))
@@ -13446,6 +13648,9 @@ initialize_breakpoint_ops (void)
ops->insert_location = bkpt_insert_location;
ops->remove_location = bkpt_remove_location;
ops->breakpoint_hit = bkpt_breakpoint_hit;
+ ops->create_sals_from_address = bkpt_create_sals_from_address;
+ ops->create_breakpoints_sal = bkpt_create_breakpoints_sal;
+ ops->decode_linespec = bkpt_decode_linespec;
/* The breakpoint_ops structure to be used in regular breakpoints. */
ops = &bkpt_breakpoint_ops;
@@ -13526,6 +13731,16 @@ initialize_breakpoint_ops (void)
ops->print_one_detail = tracepoint_print_one_detail;
ops->print_mention = tracepoint_print_mention;
ops->print_recreate = tracepoint_print_recreate;
+ ops->create_sals_from_address = tracepoint_create_sals_from_address;
+ ops->create_breakpoints_sal = tracepoint_create_breakpoints_sal;
+ ops->decode_linespec = tracepoint_decode_linespec;
+
+ /* Static tracepoints with marker (`-m'). */
+ ops = &strace_marker_breakpoint_ops;
+ *ops = tracepoint_breakpoint_ops;
+ ops->create_sals_from_address = strace_marker_create_sals_from_address;
+ ops->create_breakpoints_sal = strace_marker_create_breakpoints_sal;
+ ops->decode_linespec = strace_marker_decode_linespec;
/* Fork catchpoints. */
ops = &catch_fork_breakpoint_ops;
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index c1d3be9b611..8a8d5f27b79 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -30,6 +30,8 @@ struct get_number_or_range_state;
struct thread_info;
struct bpstats;
struct bp_location;
+struct linespec_result;
+struct linespec_sals;
/* 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
@@ -482,6 +484,37 @@ struct breakpoint_ops
/* Print to FP the CLI command that recreates this breakpoint. */
void (*print_recreate) (struct breakpoint *, struct ui_file *fp);
+
+ /* Create SALs from address string, storing the result in linespec_result.
+
+ For an explanation about the arguments, see the function
+ `create_sals_from_address_default'.
+
+ This function is called inside `create_breakpoint'. */
+ void (*create_sals_from_address) (char **, struct linespec_result *,
+ enum bptype, char *, char **);
+
+ /* This method will be responsible for creating a breakpoint given its SALs.
+ Usually, it just calls `create_breakpoints_sal' (for ordinary
+ breakpoints). However, there may be some special cases where we might
+ need to do some tweaks, e.g., see
+ `strace_marker_create_breakpoints_sal'.
+
+ This function is called inside `create_breakpoint'. */
+ void (*create_breakpoints_sal) (struct gdbarch *,
+ struct linespec_result *,
+ struct linespec_sals *, char *,
+ enum bptype, enum bpdisp, int, int,
+ int, const struct breakpoint_ops *,
+ int, int, int);
+
+ /* Given the address string (second parameter), this method decodes it
+ and provides the SAL locations related to it. For ordinary breakpoints,
+ it calls `decode_line_full'.
+
+ This function is called inside `addr_string_to_sals'. */
+ void (*decode_linespec) (struct breakpoint *, char **,
+ struct symtabs_and_lines *);
};
/* Helper for breakpoint_ops->print_recreate implementations. Prints