@@ -6997,16 +6997,10 @@ void
initialize_low (void)
{
struct sigaction sigchld_action;
- int breakpoint_len = 0;
- const unsigned char *breakpoint = NULL;
memset (&sigchld_action, 0, sizeof (sigchld_action));
set_target_ops (&linux_target_ops);
- breakpoint = the_target->breakpoint_from_pc (NULL, &breakpoint_len);
-
- set_breakpoint_data (breakpoint,
- breakpoint_len);
linux_init_signals ();
linux_ptrace_init_warnings ();
@@ -21,8 +21,6 @@
#include "server.h"
#include "regcache.h"
#include "ax.h"
-const unsigned char *breakpoint_data;
-int breakpoint_len;
#define MAX_BREAKPOINT_LEN 8
@@ -100,6 +98,10 @@ struct raw_breakpoint
breakpoint for a given PC. */
CORE_ADDR pc;
+ /* The breakpoint's insertion address, possibly with flags encoded in the pc
+ (e.g. the instruction mode on ARM). */
+ CORE_ADDR pcfull;
+
/* The breakpoint's size. */
int size;
@@ -300,6 +302,12 @@ insert_memory_breakpoint (struct raw_breakpoint *bp)
{
unsigned char buf[MAX_BREAKPOINT_LEN];
int err;
+ const unsigned char *breakpoint_data;
+ int breakpoint_len;
+ CORE_ADDR pc;
+
+ pc = bp->pcfull;
+ breakpoint_data = the_target->breakpoint_from_pc (&pc, &breakpoint_len);
if (breakpoint_data == NULL)
return 1;
@@ -349,6 +357,11 @@ remove_memory_breakpoint (struct raw_breakpoint *bp)
{
unsigned char buf[MAX_BREAKPOINT_LEN];
int err;
+ int breakpoint_len;
+ CORE_ADDR pc;
+
+ pc = bp->pcfull;
+ the_target->breakpoint_from_pc (&pc, &breakpoint_len);
/* Since there can be trap breakpoints inserted in the same address
range, we use `write_inferior_memory', which takes care of
@@ -375,15 +388,27 @@ remove_memory_breakpoint (struct raw_breakpoint *bp)
returns NULL and writes the error code to *ERR. */
static struct raw_breakpoint *
-set_raw_breakpoint_at (enum raw_bkpt_type type, CORE_ADDR where, int size,
+set_raw_breakpoint_at (enum raw_bkpt_type type, const CORE_ADDR where, int size,
int *err)
{
struct process_info *proc = current_process ();
struct raw_breakpoint *bp;
+ CORE_ADDR pc;
+ int breakpoint_len;
+
+ /* pc could be modified by breakpoint_from_pc, use the modified
+ version to find breakpoints and use the full where pc for
+ insert_point so that arch specific data can be passed. */
+ pc = where;
+
+ the_target->breakpoint_from_pc (&pc, &breakpoint_len);
+
+ if (size == 0)
+ size = breakpoint_len;
if (type == raw_bkpt_type_sw || type == raw_bkpt_type_hw)
{
- bp = find_enabled_raw_code_breakpoint_at (where, type);
+ bp = find_enabled_raw_code_breakpoint_at (pc, type);
if (bp != NULL && bp->size != size)
{
/* A different size than previously seen. The previous
@@ -396,7 +421,7 @@ set_raw_breakpoint_at (enum raw_bkpt_type type, CORE_ADDR where, int size,
}
}
else
- bp = find_raw_breakpoint_at (where, type, size);
+ bp = find_raw_breakpoint_at (pc, type, size);
if (bp != NULL)
{
@@ -405,7 +430,8 @@ set_raw_breakpoint_at (enum raw_bkpt_type type, CORE_ADDR where, int size,
}
bp = XCNEW (struct raw_breakpoint);
- bp->pc = where;
+ bp->pc = pc;
+ bp->pcfull = where;
bp->size = size;
bp->refcount = 1;
bp->raw_type = type;
@@ -774,8 +800,9 @@ set_breakpoint_at (CORE_ADDR where, int (*handler) (CORE_ADDR))
{
int err_ignored;
+ /* default breakpoint_len will be initialized downstream. */
return set_breakpoint (other_breakpoint, raw_bkpt_type_sw,
- where, breakpoint_len, handler,
+ where, 0, handler,
&err_ignored);
}
@@ -1588,13 +1615,6 @@ check_breakpoints (CORE_ADDR stop_pc)
}
}
-void
-set_breakpoint_data (const unsigned char *bp_data, int bp_len)
-{
- breakpoint_data = bp_data;
- breakpoint_len = bp_len;
-}
-
int
breakpoint_here (CORE_ADDR addr)
{
@@ -1682,6 +1702,13 @@ validate_inserted_breakpoint (struct raw_breakpoint *bp)
{
unsigned char *buf;
int err;
+ const unsigned char *breakpoint_data;
+ int breakpoint_len;
+ CORE_ADDR raw_pc;
+
+ raw_pc = bp->pcfull;
+
+ breakpoint_data = the_target->breakpoint_from_pc (&raw_pc, &breakpoint_len);
gdb_assert (bp->inserted);
gdb_assert (bp->raw_type == raw_bkpt_type_sw);
@@ -1779,10 +1806,15 @@ check_mem_read (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
for (; bp != NULL; bp = bp->next)
{
- CORE_ADDR bp_end = bp->pc + breakpoint_len;
- CORE_ADDR start, end;
+ int breakpoint_len;
+ CORE_ADDR raw_pc;
+ CORE_ADDR bp_end, start, end;
int copy_offset, copy_len, buf_offset;
+ raw_pc = bp->pcfull;
+ the_target->breakpoint_from_pc (&raw_pc, &breakpoint_len);
+ bp_end = bp->pc + breakpoint_len;
+
if (bp->raw_type != raw_bkpt_type_sw)
continue;
@@ -1868,10 +1900,17 @@ check_mem_write (CORE_ADDR mem_addr, unsigned char *buf,
for (; bp != NULL; bp = bp->next)
{
- CORE_ADDR bp_end = bp->pc + breakpoint_len;
- CORE_ADDR start, end;
+ int breakpoint_len;
+ const unsigned char *breakpoint_data;
+ CORE_ADDR raw_pc;
+ CORE_ADDR bp_end, start, end;
int copy_offset, copy_len, buf_offset;
+ raw_pc = bp->pcfull;
+ breakpoint_data =
+ the_target->breakpoint_from_pc (&raw_pc, &breakpoint_len);
+ bp_end = bp->pc + breakpoint_len;
+
if (bp->raw_type != raw_bkpt_type_sw)
continue;
@@ -1980,6 +2019,7 @@ clone_one_breakpoint (const struct breakpoint *src)
dest_raw->raw_type = src->raw->raw_type;
dest_raw->refcount = src->raw->refcount;
dest_raw->pc = src->raw->pc;
+ dest_raw->pcfull = src->raw->pcfull;
dest_raw->size = src->raw->size;
memcpy (dest_raw->old_data, src->raw->old_data, MAX_BREAKPOINT_LEN);
dest_raw->inserted = src->raw->inserted;