/* Dynamic printf class type. */
struct breakpoint_ops dprintf_breakpoint_ops;
-/* One (or perhaps two) breakpoints used for software single
- stepping. */
-
-static struct breakpoint *single_step_breakpoints;
-
/* The style in which to perform a dynamic printf. This is a user
option because different output options have different tradeoffs;
if GDB does the printing, there is better error handling if there
/* BL is never in moribund_locations by our callers. */
gdb_assert (bl->owner != NULL);
- if (bl->owner->enable_state == bp_permanent)
+ if (bl->permanent)
/* Permanent breakpoints cannot be inserted or removed. */
return 0;
/* BL is never in moribund_locations by our callers. */
gdb_assert (bl->owner != NULL);
- if (bl->owner->enable_state == bp_permanent)
+ if (bl->permanent)
/* Permanent breakpoints cannot be inserted or removed. */
return 0;
struct bp_location *bl, **blp_tmp;
ALL_BP_LOCATIONS (bl, blp_tmp)
- if (bl->pspace == current_program_space)
+ if (bl->pspace == current_program_space
+ && !bl->permanent)
bl->inserted = 0;
}
if (gdbarch_has_global_breakpoints (target_gdbarch ()))
return;
- ALL_BP_LOCATIONS (bl, blp_tmp)
- {
- /* ALL_BP_LOCATIONS bp_location has BL->OWNER always non-NULL. */
- if (bl->pspace == pspace
- && bl->owner->enable_state != bp_permanent)
- bl->inserted = 0;
- }
+ mark_breakpoints_out ();
ALL_BREAKPOINTS_SAFE (b, b_tmp)
{
/* ALL_BP_LOCATIONS bp_location has BL->OWNER always non-NULL. */
if ((breakpoint_enabled (bl->owner)
- || bl->owner->enable_state == bp_permanent)
+ || bl->permanent)
&& breakpoint_location_address_match (bl, aspace, pc))
{
if (overlay_debugging
&& section_is_overlay (bl->section)
&& !section_is_mapped (bl->section))
continue; /* unmapped overlay -- can't be a match */
- else if (bl->owner->enable_state == bp_permanent)
+ else if (bl->permanent)
return permanent_breakpoint_here;
else
any_breakpoint_here = 1;
}
return 0;
}
-
-/* breakpoint_thread_match (PC, PTID) returns true if the breakpoint at
- PC is valid for process/thread PTID. */
-
-int
-breakpoint_thread_match (struct address_space *aspace, CORE_ADDR pc,
- ptid_t ptid)
-{
- struct bp_location *bl, **blp_tmp;
- /* The thread and task IDs associated to PTID, computed lazily. */
- int thread = -1;
- int task = 0;
-
- ALL_BP_LOCATIONS (bl, blp_tmp)
- {
- if (bl->loc_type != bp_loc_software_breakpoint
- && bl->loc_type != bp_loc_hardware_breakpoint)
- continue;
-
- /* ALL_BP_LOCATIONS bp_location has bl->OWNER always non-NULL. */
- if (!breakpoint_enabled (bl->owner)
- && bl->owner->enable_state != bp_permanent)
- continue;
-
- if (!breakpoint_location_address_match (bl, aspace, pc))
- continue;
-
- if (bl->owner->thread != -1)
- {
- /* This is a thread-specific breakpoint. Check that ptid
- matches that thread. If thread hasn't been computed yet,
- it is now time to do so. */
- if (thread == -1)
- thread = pid_to_thread_id (ptid);
- if (bl->owner->thread != thread)
- continue;
- }
-
- if (bl->owner->task != 0)
- {
- /* This is a task-specific breakpoint. Check that ptid
- matches that task. If task hasn't been computed yet,
- it is now time to do so. */
- if (task == 0)
- task = ada_get_task_number (ptid);
- if (bl->owner->task != task)
- continue;
- }
-
- if (overlay_debugging
- && section_is_overlay (bl->section)
- && !section_is_mapped (bl->section))
- continue; /* unmapped overlay -- can't be a match */
-
- return 1;
- }
-
- return 0;
-}
\f
/* bpstat stuff. External routines' interfaces are documented
ALL_BREAKPOINTS (b)
{
- if (!breakpoint_enabled (b) && b->enable_state != bp_permanent)
+ if (!breakpoint_enabled (b))
continue;
for (bl = b->loc; bl != NULL; bl = bl->next)
if (b->disposition == disp_disable)
{
--(b->enable_count);
- if (b->enable_count <= 0
- && b->enable_state != bp_permanent)
+ if (b->enable_count <= 0)
b->enable_state = bp_disabled;
removed_any = 1;
}
((b->enable_state == bp_disabled
|| b->enable_state == bp_call_disabled)
? " (disabled)"
- : b->enable_state == bp_permanent
- ? " (permanent)"
: ""),
(others > 1) ? ","
: ((others == 1) ? " and" : ""));
if (sal.section)
return get_objfile_arch (sal.section->objfile);
if (sal.symtab)
- return get_objfile_arch (sal.symtab->objfile);
+ return get_objfile_arch (SYMTAB_OBJFILE (sal.symtab));
return NULL;
}
{
struct bp_location *bl;
- b->enable_state = bp_permanent;
-
/* By definition, permanent breakpoints are already present in the
code. Mark all locations as inserted. For now,
make_breakpoint_permanent is called in just one place, so it's
hard to say if it's reasonable to have permanent breakpoint with
multiple locations or not, but it's easy to implement. */
for (bl = b->loc; bl; bl = bl->next)
- bl->inserted = 1;
+ {
+ bl->permanent = 1;
+ bl->inserted = 1;
+ }
}
/* Call this routine when stepping and nexting to enable a breakpoint
ptid_t ptid;
struct target_waitstatus last;
struct syscall s;
+ struct gdbarch *gdbarch = bs->bp_location_at->gdbarch;
get_last_target_status (&ptid, &last);
- get_syscall_by_number (last.value.syscall_number, &s);
+ get_syscall_by_number (gdbarch, last.value.syscall_number, &s);
annotate_catchpoint (b->number);
struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
struct value_print_options opts;
struct ui_out *uiout = current_uiout;
+ struct gdbarch *gdbarch = b->loc->gdbarch;
get_user_print_options (&opts);
/* Field 4, the address, is omitted (which makes the columns not
{
char *x = text;
struct syscall s;
- get_syscall_by_number (iter, &s);
+ get_syscall_by_number (gdbarch, iter, &s);
if (s.name != NULL)
text = xstrprintf ("%s%s, ", text, s.name);
print_mention_catch_syscall (struct breakpoint *b)
{
struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
+ struct gdbarch *gdbarch = b->loc->gdbarch;
if (c->syscalls_to_be_caught)
{
i++)
{
struct syscall s;
- get_syscall_by_number (iter, &s);
+ get_syscall_by_number (gdbarch, iter, &s);
if (s.name)
printf_filtered (" '%s' [%d]", s.name, s.number);
print_recreate_catch_syscall (struct breakpoint *b, struct ui_file *fp)
{
struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
+ struct gdbarch *gdbarch = b->loc->gdbarch;
fprintf_unfiltered (fp, "catch syscall");
{
struct syscall s;
- get_syscall_by_number (iter, &s);
+ get_syscall_by_number (gdbarch, iter, &s);
if (s.name)
fprintf_unfiltered (fp, " %s", s.name);
else
}
\f
+static int bp_loc_is_permanent (struct bp_location *loc);
+
static struct bp_location *
add_location_to_breakpoint (struct breakpoint *b,
const struct symtab_and_line *sal)
set_breakpoint_location_function (loc,
sal->explicit_pc || sal->explicit_line);
+
+ if (bp_loc_is_permanent (loc))
+ {
+ loc->inserted = 1;
+ loc->permanent = 1;
+ }
+
return loc;
}
\f
gdb_assert (loc != NULL);
+ /* bp_call_dummy breakpoint locations are usually memory locations
+ where GDB just wrote a breakpoint instruction, making it look
+ as if there is a permanent breakpoint at that location. Considering
+ it permanent makes GDB rely on that breakpoint instruction to stop
+ the program, thus removing the need to insert its own breakpoint
+ there. This is normally expected to work, except that some versions
+ of QEMU (Eg: QEMU 2.0.0 for SPARC) just report a fatal problem (Trap
+ 0x02 while interrupts disabled, Error state) instead of reporting
+ a SIGTRAP. QEMU should probably be fixed, but in the interest of
+ compatibility with versions that behave this way, we always consider
+ bp_call_dummy breakpoint locations as non-permanent. */
+ if (loc->owner->type == bp_call_dummy)
+ return 0;
+
addr = loc->address;
bpoint = gdbarch_breakpoint_from_pc (loc->gdbarch, &addr, &len);
loc->inserted = 1;
}
- if (bp_loc_is_permanent (loc))
- make_breakpoint_permanent (b);
-
if (b->cond_string)
{
const char *arg = b->cond_string;
const struct block *b;
struct symbol *sym;
- bv = blockvector_for_pc_sect (sal->pc, 0, &b, sal->symtab);
+ bv = blockvector_for_pc_sect (sal->pc, 0, &b,
+ SYMTAB_COMPUNIT (sal->symtab));
if (bv != NULL)
{
sym = block_linkage_function (b);
if (sym != NULL)
{
- fixup_symbol_section (sym, sal->symtab->objfile);
- sal->section = SYMBOL_OBJ_SECTION (sal->symtab->objfile, sym);
+ fixup_symbol_section (sym, SYMTAB_OBJFILE (sal->symtab));
+ sal->section = SYMBOL_OBJ_SECTION (SYMTAB_OBJFILE (sal->symtab),
+ sym);
}
else
{
{
VEC(int) *result = NULL;
struct cleanup *cleanup = make_cleanup (VEC_cleanup (int), &result);
+ struct gdbarch *gdbarch = target_gdbarch ();
while (*arg != '\0')
{
/* Check if the user provided a syscall name or a number. */
syscall_number = (int) strtol (cur_name, &endptr, 0);
if (*endptr == '\0')
- get_syscall_by_number (syscall_number, &s);
+ get_syscall_by_number (gdbarch, syscall_number, &s);
else
{
/* We have a name. Let's check if it's valid and convert it
to a number. */
- get_syscall_by_name (cur_name, &s);
+ get_syscall_by_name (gdbarch, cur_name, &s);
if (s.number == UNKNOWN_SYSCALL)
/* Here we have to issue an error instead of a warning,
to get the syscall XML file loaded or, most important,
to display a warning to the user if there's no XML file
for his/her architecture. */
- get_syscall_by_number (0, &s);
+ get_syscall_by_number (gdbarch, 0, &s);
/* The allowed syntax is:
catch syscall
/* A comparison function for bp_location AP and BP being interfaced to
qsort. Sort elements primarily by their ADDRESS (no matter what
does breakpoint_address_is_meaningful say for its OWNER),
- secondarily by ordering first bp_permanent OWNERed elements and
+ secondarily by ordering first permanent elements and
terciarily just ensuring the array is sorted stable way despite
qsort being an unstable algorithm. */
{
struct bp_location *a = *(void **) ap;
struct bp_location *b = *(void **) bp;
- /* A and B come from existing breakpoints having non-NULL OWNER. */
- int a_perm = a->owner->enable_state == bp_permanent;
- int b_perm = b->owner->enable_state == bp_permanent;
if (a->address != b->address)
return (a->address > b->address) - (a->address < b->address);
- (a->pspace->num < b->pspace->num));
/* Sort permanent breakpoints first. */
- if (a_perm != b_perm)
- return (a_perm < b_perm) - (a_perm > b_perm);
+ if (a->permanent != b->permanent)
+ return (a->permanent < b->permanent) - (a->permanent > b->permanent);
/* Make the internal GDB representation stable across GDB runs
where A and B memory inside GDB can differ. Breakpoint locations of
}
/* Permanent breakpoint should always be inserted. */
- if (b->enable_state == bp_permanent && ! loc->inserted)
+ if (loc->permanent && ! loc->inserted)
internal_error (__FILE__, __LINE__,
_("allegedly permanent breakpoint is not "
"actually inserted"));
/* Clear the condition modification flag. */
loc->condition_changed = condition_unchanged;
- if ((*loc_first_p)->owner->enable_state == bp_permanent && loc->inserted
- && b->enable_state != bp_permanent)
+ if (loc->inserted && !loc->permanent
+ && (*loc_first_p)->permanent)
internal_error (__FILE__, __LINE__,
_("another breakpoint was inserted on top of "
"a permanent breakpoint"));
}
}
- /* Update locations of permanent breakpoints. */
- if (b->enable_state == bp_permanent)
- make_breakpoint_permanent (b);
-
/* If possible, carry over 'disable' status from existing
breakpoints. */
{
if (bpt->type == bp_watchpoint_scope)
return;
- /* You can't disable permanent breakpoints. */
- if (bpt->enable_state == bp_permanent)
- return;
-
bpt->enable_state = bp_disabled;
/* Mark breakpoint locations modified. */
}
}
- if (bpt->enable_state != bp_permanent)
- bpt->enable_state = bp_enabled;
-
bpt->enable_state = bp_enabled;
/* Mark breakpoint locations modified. */
struct symtab_and_line sal;
CORE_ADDR pc = next_pc;
- if (single_step_breakpoints == NULL)
- single_step_breakpoints = new_single_step_breakpoint (tp->num, gdbarch);
+ if (tp->control.single_step_breakpoints == NULL)
+ {
+ tp->control.single_step_breakpoints
+ = new_single_step_breakpoint (tp->num, gdbarch);
+ }
sal = find_pc_line (pc, 0);
sal.pc = pc;
sal.section = find_pc_overlay (pc);
sal.explicit_pc = 1;
- add_location_to_breakpoint (single_step_breakpoints, &sal);
+ add_location_to_breakpoint (tp->control.single_step_breakpoints, &sal);
update_global_location_list (UGLL_INSERT);
}
-/* Check if the breakpoints used for software single stepping
- were inserted or not. */
+/* See breakpoint.h. */
int
-single_step_breakpoints_inserted (void)
-{
- return (single_step_breakpoints != NULL);
-}
-
-/* Remove and delete any breakpoints used for software single step. */
-
-void
-remove_single_step_breakpoints (void)
-{
- gdb_assert (single_step_breakpoints != NULL);
-
- delete_breakpoint (single_step_breakpoints);
-
- single_step_breakpoints = NULL;
-}
-
-/* Delete software single step breakpoints without removing them from
- the inferior. This is intended to be used if the inferior's address
- space where they were inserted is already gone, e.g. after exit or
- exec. */
-
-void
-cancel_single_step_breakpoints (void)
-{
- /* We don't really need to (or should) delete them here. After an
- exit, breakpoint_init_inferior deletes it. After an exec,
- update_breakpoints_after_exec does it. Just clear our
- reference. */
- single_step_breakpoints = NULL;
-}
-
-/* Check whether any location of BP is inserted at PC. */
-
-static int
breakpoint_has_location_inserted_here (struct breakpoint *bp,
struct address_space *aspace,
CORE_ADDR pc)
single_step_breakpoint_inserted_here_p (struct address_space *aspace,
CORE_ADDR pc)
{
- return (single_step_breakpoints != NULL
- && breakpoint_has_location_inserted_here (single_step_breakpoints,
- aspace, pc));
+ struct breakpoint *bpt;
+
+ ALL_BREAKPOINTS (bpt)
+ {
+ if (bpt->type == bp_single_step
+ && breakpoint_has_location_inserted_here (bpt, aspace, pc))
+ return 1;
+ }
+ return 0;
}
/* Returns 0 if 'bp' is NOT a syscall catchpoint,
catch_syscall_completer (struct cmd_list_element *cmd,
const char *text, const char *word)
{
- const char **list = get_syscall_names ();
+ const char **list = get_syscall_names (get_current_arch ());
VEC (char_ptr) *retlist
= (list == NULL) ? NULL : complete_on_enum (list, word, word);
struct bp_location **locp, *loc;
ALL_BP_LOCATIONS (loc, locp)
- if (loc->symtab != NULL && loc->symtab->objfile == objfile)
+ if (loc->symtab != NULL && SYMTAB_OBJFILE (loc->symtab) == objfile)
loc->symtab = NULL;
}