/* Everything about breakpoints, for GDB.
- Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
Free Software Foundation, Inc.
This file is part of GDB.
#include "gdb_string.h"
#include "demangle.h"
#include "annotate.h"
+#include "symfile.h"
+#include "objfiles.h"
/* local function prototypes */
set_raw_breakpoint PARAMS ((struct symtab_and_line));
static void
-check_duplicates PARAMS ((CORE_ADDR));
+check_duplicates PARAMS ((CORE_ADDR, asection *));
static void
-describe_other_breakpoints PARAMS ((CORE_ADDR));
+describe_other_breakpoints PARAMS ((CORE_ADDR, asection *));
static void
breakpoints_info PARAMS ((char *, int));
extern int addressprint; /* Print machine addresses? */
+#if defined (GET_LONGJMP_TARGET) || defined (SOLIB_ADD)
+static int internal_breakpoint_number = -1;
+#endif
+
/* Are we executing breakpoint commands? */
static int executing_breakpoint_commands;
b? (tmp=b->next, 1): 0; \
b = tmp)
+/* True if SHIFT_INST_REGS defined, false otherwise. */
+
+int must_shift_inst_regs =
+#if defined(SHIFT_INST_REGS)
+1
+#else
+0
+#endif
+;
+
/* True if breakpoint hit counts should be displayed in breakpoint info. */
int show_breakpoint_hit_counts = 1;
if (b->type == bp_hardware_breakpoint)
val = target_insert_hw_breakpoint(b->address, b->shadow_contents);
else
- val = target_insert_breakpoint(b->address, b->shadow_contents);
+ {
+ /* Check to see if breakpoint is in an overlay section;
+ if so, we should set the breakpoint at the LMA address.
+ Only if the section is currently mapped should we ALSO
+ set a break at the VMA address. */
+ if (overlay_debugging && b->section &&
+ section_is_overlay (b->section))
+ {
+ CORE_ADDR addr;
+
+ addr = overlay_unmapped_address (b->address, b->section);
+ val = target_insert_breakpoint (addr, b->shadow_contents);
+ /* This would be the time to check val, to see if the
+ breakpoint write to the load address succeeded.
+ However, this might be an ordinary occurrance, eg. if
+ the unmapped overlay is in ROM. */
+ val = 0; /* in case unmapped address failed */
+ if (section_is_mapped (b->section))
+ val = target_insert_breakpoint (b->address,
+ b->shadow_contents);
+ }
+ else /* ordinary (non-overlay) address */
+ val = target_insert_breakpoint(b->address, b->shadow_contents);
+ }
if (val)
{
/* Can't set the breakpoint. */
within_current_scope = 1;
else
{
- struct frame_info *fi =
- find_frame_addr_in_frame_chain (b->watchpoint_frame);
+ struct frame_info *fi;
+
+ /* There might be no current frame at this moment if we are
+ resuming from a step over a breakpoint.
+ Set up current frame before trying to find the watchpoint
+ frame. */
+ get_current_frame ();
+ fi = find_frame_addr_in_frame_chain (b->watchpoint_frame);
within_current_scope = (fi != NULL);
if (within_current_scope)
select_frame (fi, -1);
Hardware watchpoint %d deleted because the program has left the block in\n\
which its expression is valid.\n", b->number);
if (b->related_breakpoint)
- {
- b->related_breakpoint->enable = disable;
- b->related_breakpoint->disposition = del_at_next_stop;
- }
- b->enable = disable;
+ b->related_breakpoint->disposition = del_at_next_stop;
b->disposition = del_at_next_stop;
}
if (b->type == bp_hardware_breakpoint)
val = target_remove_hw_breakpoint(b->address, b->shadow_contents);
else
- val = target_remove_breakpoint(b->address, b->shadow_contents);
+ {
+ /* Check to see if breakpoint is in an overlay section;
+ if so, we should remove the breakpoint at the LMA address.
+ If that is not equal to the raw address, then we should
+ presumable remove the breakpoint there as well. */
+ if (overlay_debugging && b->section &&
+ section_is_overlay (b->section))
+ {
+ CORE_ADDR addr;
+
+ addr = overlay_unmapped_address (b->address, b->section);
+ val = target_remove_breakpoint (addr, b->shadow_contents);
+ /* This would be the time to check val, to see if the
+ shadow breakpoint write to the load address succeeded.
+ However, this might be an ordinary occurrance, eg. if
+ the unmapped overlay is in ROM. */
+ val = 0; /* in case unmapped address failed */
+ if (section_is_mapped (b->section))
+ val = target_remove_breakpoint (b->address,
+ b->shadow_contents);
+ }
+ else /* ordinary (non-overlay) address */
+ val = target_remove_breakpoint(b->address, b->shadow_contents);
+ }
if (val)
return val;
b->inserted = 0;
at that address. */
if (v->lval == lval_memory)
{
- int addr, len;
+ int addr, len, type;
addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
len = TYPE_LENGTH (VALUE_TYPE (v));
- val = target_remove_watchpoint (addr, len, b->type);
+ type = 0;
+ if (b->type == bp_read_watchpoint)
+ type = 1;
+ else if (b->type == bp_access_watchpoint)
+ type = 2;
+
+ val = target_remove_watchpoint (addr, len, type);
if (val == -1)
b->inserted = 1;
val = 0;
register struct breakpoint *b;
ALL_BREAKPOINTS (b)
- if (b->enable != disabled
- && b->enable != shlib_disabled
- && b->address == pc)
- return 1;
+ if (b->enable == enabled
+ && b->address == pc) /* bp is enabled and matches pc */
+ if (overlay_debugging &&
+ section_is_overlay (b->section) &&
+ !section_is_mapped (b->section))
+ continue; /* unmapped overlay -- can't be a match */
+ else
+ return 1;
+
+ return 0;
+}
+
+/* breakpoint_inserted_here_p (PC) is just like breakpoint_here_p(), but it
+ only returns true if there is actually a breakpoint inserted at PC. */
+
+int
+breakpoint_inserted_here_p (pc)
+ CORE_ADDR pc;
+{
+ register struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ if (b->inserted
+ && b->address == pc) /* bp is inserted and matches pc */
+ if (overlay_debugging &&
+ section_is_overlay (b->section) &&
+ !section_is_mapped (b->section))
+ continue; /* unmapped overlay -- can't be a match */
+ else
+ return 1;
return 0;
}
frame_in_dummy (frame)
struct frame_info *frame;
{
+#ifdef CALL_DUMMY
+#ifdef USE_GENERIC_DUMMY_FRAMES
+ return generic_pc_in_call_dummy (frame->pc, frame->frame);
+#else
struct breakpoint *b;
-#ifdef CALL_DUMMY
ALL_BREAKPOINTS (b)
{
- static unsigned LONGEST dummy[] = CALL_DUMMY;
+ static ULONGEST dummy[] = CALL_DUMMY;
if (b->type == bp_call_dummy
&& b->frame == frame->frame
&& frame->pc <= b->address)
return 1;
}
+#endif /* GENERIC_DUMMY_FRAMES */
#endif /* CALL_DUMMY */
return 0;
}
&& b->enable != shlib_disabled
&& b->address == pc
&& (b->thread == -1 || b->thread == thread))
- return 1;
+ if (overlay_debugging &&
+ section_is_overlay (b->section) &&
+ !section_is_mapped (b->section))
+ continue; /* unmapped overlay -- can't be a match */
+ else
+ return 1;
return 0;
}
Watchpoint %d deleted because the program has left the block in\n\
which its expression is valid.\n", bs->breakpoint_at->number);
if (b->related_breakpoint)
- {
- b->related_breakpoint->enable = disable;
- b->related_breakpoint->disposition = del_at_next_stop;
- }
- b->enable = disable;
+ b->related_breakpoint->disposition = del_at_next_stop;
b->disposition = del_at_next_stop;
return WP_DELETED;
{
register struct breakpoint *b, *temp;
CORE_ADDR bp_addr;
-#if DECR_PC_AFTER_BREAK != 0 || defined (SHIFT_INST_REGS)
/* True if we've hit a breakpoint (as opposed to a watchpoint). */
int real_breakpoint = 0;
-#endif
/* Root of the chain of bpstat's */
struct bpstats root_bs[1];
/* Pointer to the last thing in the chain currently. */
&& b->type != bp_hardware_watchpoint
&& b->type != bp_read_watchpoint
&& b->type != bp_access_watchpoint
- && b->type != bp_hardware_breakpoint
- && b->address != bp_addr)
- continue;
+ && b->type != bp_hardware_breakpoint) /* a non-watchpoint bp */
+ if (b->address != bp_addr || /* address doesn't match or */
+ (overlay_debugging && /* overlay doesn't match */
+ section_is_overlay (b->section) &&
+ !section_is_mapped (b->section)))
+ continue;
if (b->type == bp_hardware_breakpoint
&& b->address != (bp_addr - DECR_PC_AFTER_HW_BREAK))
/* Error from catch_errors. */
printf_filtered ("Watchpoint %d deleted.\n", b->number);
if (b->related_breakpoint)
- {
- b->related_breakpoint->enable = disable;
- b->related_breakpoint->disposition = del_at_next_stop;
- }
- b->enable = disable;
+ b->related_breakpoint->disposition = del_at_next_stop;
b->disposition = del_at_next_stop;
/* We've already printed what needs to be printed. */
bs->print_it = print_it_done;
/* Error from catch_errors. */
printf_filtered ("Watchpoint %d deleted.\n", b->number);
if (b->related_breakpoint)
- {
- b->related_breakpoint->enable = disable;
- b->related_breakpoint->disposition = del_at_next_stop;
- }
- b->enable = disable;
+ b->related_breakpoint->disposition = del_at_next_stop;
b->disposition = del_at_next_stop;
/* We've already printed what needs to be printed. */
bs->print_it = print_it_done;
break;
}
}
-#if DECR_PC_AFTER_BREAK != 0 || defined (SHIFT_INST_REGS)
- else
+ else if (DECR_PC_AFTER_BREAK != 0 || must_shift_inst_regs)
real_breakpoint = 1;
-#endif
if (b->frame && b->frame != (get_current_frame ())->frame)
bs->stop = 0;
bs->next = NULL; /* Terminate the chain */
bs = root_bs->next; /* Re-grab the head of the chain */
-#if DECR_PC_AFTER_BREAK != 0 || defined (SHIFT_INST_REGS)
- if (bs)
+
+ if ((DECR_PC_AFTER_BREAK != 0 || must_shift_inst_regs) && bs)
{
if (real_breakpoint)
{
#endif /* No SHIFT_INST_REGS. */
}
}
-#endif /* DECR_PC_AFTER_BREAK != 0. */
/* The value of a hardware watchpoint hasn't changed, but the
intermediate memory locations we are watching may have. */
last_addr = b->address;
if (b->source_file)
{
- sym = find_pc_function (b->address);
+ sym = find_pc_sect_function (b->address, b->section);
if (sym)
{
fputs_filtered ("in ", gdb_stdout);
/* Print a message describing any breakpoints set at PC. */
static void
-describe_other_breakpoints (pc)
- register CORE_ADDR pc;
+describe_other_breakpoints (pc, section)
+ CORE_ADDR pc;
+ asection *section;
{
register int others = 0;
register struct breakpoint *b;
ALL_BREAKPOINTS (b)
if (b->address == pc)
- others++;
+ if (overlay_debugging == 0 ||
+ b->section == section)
+ others++;
if (others > 0)
{
printf_filtered ("Note: breakpoint%s ", (others > 1) ? "s" : "");
ALL_BREAKPOINTS (b)
if (b->address == pc)
- {
- others--;
- printf_filtered
- ("%d%s%s ",
- b->number,
- ((b->enable == disabled || b->enable == shlib_disabled)
- ? " (disabled)" : ""),
- (others > 1) ? "," : ((others == 1) ? " and" : ""));
- }
+ if (overlay_debugging == 0 ||
+ b->section == section)
+ {
+ others--;
+ printf_filtered
+ ("%d%s%s ",
+ b->number,
+ ((b->enable == disabled || b->enable == shlib_disabled)
+ ? " (disabled)" : ""),
+ (others > 1) ? "," : ((others == 1) ? " and" : ""));
+ }
printf_filtered ("also set at pc ");
print_address_numeric (pc, 1, gdb_stdout);
printf_filtered (".\n");
This is so that the bpt instruction is only inserted once. */
static void
-check_duplicates (address)
+check_duplicates (address, section)
CORE_ADDR address;
+ asection *section;
{
register struct breakpoint *b;
register int count = 0;
ALL_BREAKPOINTS (b)
if (b->enable != disabled
&& b->enable != shlib_disabled
- && b->address == address)
+ && b->address == address
+ && (overlay_debugging == 0 || b->section == section))
{
count++;
b->duplicate = count > 1;
else
b->source_file = savestring (sal.symtab->filename,
strlen (sal.symtab->filename));
+ b->section = sal.section;
b->language = current_language->la_language;
b->input_radix = input_radix;
b->thread = -1;
b1->next = b;
}
- check_duplicates (sal.pc);
+ check_duplicates (sal.pc, sal.section);
breakpoints_changed ();
return b;
}
-static int internal_breakpoint_number = -1;
-
#ifdef GET_LONGJMP_TARGET
static void
struct symtab_and_line sal;
struct breakpoint *b;
+ INIT_SAL (&sal); /* initialize to zeroes */
if (func_name != NULL)
{
struct minimal_symbol *m;
else
return;
}
- else
- sal.pc = 0;
-
- sal.symtab = NULL;
- sal.line = 0;
-
+ sal.section = find_pc_overlay (sal.pc);
b = set_raw_breakpoint (sal);
if (!b) return;
if (b->type == bp_longjmp)
{
b->enable = enabled;
- check_duplicates (b->address);
+ check_duplicates (b->address, b->section);
}
}
|| b->type == bp_longjmp_resume)
{
b->enable = disabled;
- check_duplicates (b->address);
+ check_duplicates (b->address, b->section);
}
}
struct breakpoint *b;
struct symtab_and_line sal;
+ INIT_SAL (&sal); /* initialize to zeroes */
sal.pc = address;
- sal.symtab = NULL;
- sal.line = 0;
+ sal.section = find_pc_overlay (sal.pc);
b = set_raw_breakpoint (sal);
b->number = internal_breakpoint_number--;
b->disposition = donttouch;
b->frame = frame->frame;
else
b->frame = 0;
- check_duplicates (b->address);
+ check_duplicates (b->address, b->section);
return;
}
}
sals.sals = NULL;
sals.nelts = 0;
- sal.line = sal.pc = sal.end = 0;
- sal.symtab = 0;
+ INIT_SAL (&sal); /* initialize to zeroes */
/* If no arg given, or if first arg is 'if ', use the default breakpoint. */
sal.pc = default_breakpoint_address;
sal.line = default_breakpoint_line;
sal.symtab = default_breakpoint_symtab;
+ sal.section = find_pc_overlay (sal.pc);
sals.sals[0] = sal;
sals.nelts = 1;
}
sal = sals.sals[i];
if (from_tty)
- describe_other_breakpoints (sal.pc);
+ describe_other_breakpoints (sal.pc, sal.section);
b = set_raw_breakpoint (sal);
set_breakpoint_count (breakpoint_count + 1);
b->enable = enabled;
b->disposition = tempflag ? del : donttouch;
-
mention (b);
}
{
CORE_ADDR pc;
- if (sal->pc == 0 && sal->symtab != 0)
+ if (sal->pc == 0 && sal->symtab != NULL)
{
pc = find_line_pc (sal->symtab, sal->line);
if (pc == 0)
sal->line, sal->symtab->filename);
sal->pc = pc;
}
+
+ if (sal->section == 0 && sal->symtab != NULL)
+ {
+ struct blockvector *bv;
+ struct block *b;
+ struct symbol *sym;
+ int index;
+
+ bv = blockvector_for_pc_sect (sal->pc, 0, &index, sal->symtab);
+ b = BLOCKVECTOR_BLOCK (bv, index);
+ sym = block_function (b);
+ if (sym != NULL)
+ {
+ fixup_symbol_section (sym, sal->symtab->objfile);
+ sal->section = SYMBOL_BFD_SECTION (block_function (b));
+ }
+ }
}
void
char *cond_start = NULL;
char *cond_end = NULL;
struct expression *cond = NULL;
- int i, other_type_used, target_resources_ok;
+ int i, other_type_used, target_resources_ok = 0;
enum bptype bp_type;
int mem_cnt = 0;
- sal.pc = 0;
- sal.symtab = NULL;
- sal.line = 0;
+ INIT_SAL (&sal); /* initialize to zeroes */
/* Parse arguments. */
innermost_block = NULL;
expression. */
if (innermost_block)
{
- struct breakpoint *scope_breakpoint;
- struct symtab_and_line scope_sal;
-
if (prev_frame)
{
- scope_sal.pc = get_frame_pc (prev_frame);
- scope_sal.symtab = NULL;
- scope_sal.line = 0;
-
+ struct breakpoint *scope_breakpoint;
+ struct symtab_and_line scope_sal;
+
+ INIT_SAL (&scope_sal); /* initialize to zeroes */
+ scope_sal.pc = get_frame_pc (prev_frame);
+ scope_sal.section = find_pc_overlay (scope_sal.pc);
+
scope_breakpoint = set_raw_breakpoint (scope_sal);
set_breakpoint_count (breakpoint_count + 1);
scope_breakpoint->number = breakpoint_count;
#if 0
if (function (p))
{
- struct sal_chain *next
- = (struct sal_chain *)alloca (sizeof (struct sal_chain));
+ struct sal_chain *next = (struct sal_chain *)
+ alloca (sizeof (struct sal_chain));
next->next = sal_chain;
next->sal = get_catch_sal (p);
sal_chain = next;
char *save_arg;
int i;
- sal.line = sal.pc = sal.end = 0;
- sal.symtab = 0;
+ INIT_SAL (&sal); /* initialize to zeroes */
/* If no arg given, or if first arg is 'if ', all active catch clauses
are breakpointed. */
sal = sals.sals[i];
if (from_tty)
- describe_other_breakpoints (sal.pc);
+ describe_other_breakpoints (sal.pc, sal.section);
b = set_raw_breakpoint (sal);
set_breakpoint_count (breakpoint_count + 1);
struct breakpoint *
set_breakpoint_sal (sal)
-struct symtab_and_line sal;
+ struct symtab_and_line sal;
{
struct breakpoint *b;
b = set_raw_breakpoint (sal);
}
else
{
- sals.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line));
+ sals.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ INIT_SAL (&sal); /* initialize to zeroes */
sal.line = default_breakpoint_line;
sal.symtab = default_breakpoint_symtab;
- sal.pc = 0;
if (sal.symtab == 0)
error ("No source file specified.");
But if sal.pc is zero, clear all bpts on specified line. */
sal = sals.sals[i];
found = (struct breakpoint *) 0;
+
while (breakpoint_chain
&& (sal.pc
- ? breakpoint_chain->address == sal.pc
+ ? (breakpoint_chain->address == sal.pc &&
+ (overlay_debugging == 0 ||
+ breakpoint_chain->section == sal.section))
: (breakpoint_chain->source_file != NULL
&& sal.symtab != NULL
&& STREQ (breakpoint_chain->source_file,
&& b->next->type != bp_read_watchpoint
&& b->next->type != bp_access_watchpoint
&& (sal.pc
- ? b->next->address == sal.pc
+ ? (b->next->address == sal.pc &&
+ (overlay_debugging == 0 ||
+ b->next->section == sal.section))
: (b->next->source_file != NULL
&& sal.symtab != NULL
&& STREQ (b->next->source_file, sal.symtab->filename)
break;
}
- check_duplicates (bpt->address);
+ check_duplicates (bpt->address, bpt->section);
/* If this breakpoint was inserted, and there is another breakpoint
at the same address, we need to insert the other breakpoint. */
if (bpt->inserted
{
ALL_BREAKPOINTS (b)
if (b->address == bpt->address
+ && b->section == bpt->section
&& !b->duplicate
&& b->enable != disabled
&& b->enable != shlib_disabled)
char *arg;
int from_tty;
{
+ struct breakpoint *b, *temp;
if (arg == 0)
{
|| (breakpoint_chain && query ("Delete all breakpoints? ")))
{
/* No arg; clear all breakpoints. */
- while (breakpoint_chain)
- delete_breakpoint (breakpoint_chain);
+ ALL_BREAKPOINTS_SAFE(b, temp)
+ /* do not delete call-dummy breakpoint unles explicitly named! */
+ if (b->type != bp_call_dummy)
+ delete_breakpoint (b);
}
}
else
strlen (sals.sals[i].symtab->filename));
b->line_number = sals.sals[i].line;
b->address = sals.sals[i].pc;
-
- check_duplicates (b->address);
+ check_duplicates (b->address, b->section);
mention (b);
rather than once for every breakpoint. */
breakpoints_changed ();
}
+ b->section = sals.sals[i].section;
b->enable = save_enable; /* Restore it, this worked. */
}
free ((PTR)sals.sals);
create_longjmp_breakpoint ("longjmp");
create_longjmp_breakpoint ("_longjmp");
create_longjmp_breakpoint ("siglongjmp");
+ create_longjmp_breakpoint ("_siglongjmp");
create_longjmp_breakpoint (NULL);
#endif
bpt->enable = disabled;
- check_duplicates (bpt->address);
+ check_duplicates (bpt->address, bpt->section);
if (modify_breakpoint_hook)
modify_breakpoint_hook (bpt);
bpt->enable = enabled;
bpt->disposition = disposition;
- check_duplicates (bpt->address);
+ check_duplicates (bpt->address, bpt->section);
breakpoints_changed ();
if (bpt->type == bp_watchpoint || bpt->type == bp_hardware_watchpoint ||