Add the target_ops needed for software breakpoints in GDBServer.
This patch is in preparation for software breakpoints on ARM linux. It refactors breakpoint and breakpoint_len into breakpoint_kind_from_pc and sw_breakpoint_from kind to prepare the case where we have multiple types of breakpoints. Kind is the type of breakpoint (hardware or software) to be inserted, usually it is the lenght of the software breakpoint but can be something else depending on the target. This patch introduces the linux_target_ops breakpoint_kind_from_pc and sw_breakpoint_from_kind. breakpoint_kind_from_pc returns the breakpoint kind and adjusts the PC to the real memory location in case a flag was present in the PC. E.g the instruction mode on ARM. sw_breakpoint_from_kind returns the software breakpoint for this kind as a string of bytes, the length of the breakpoint is adjusted for the breakpoint's size in memory. For targets that have only one kind of breakpoint, the default value 0 is returned by linux_breakpoint_kind_from_pc so that not all targets need to implement the breakpoint_kind_from_pc operation. No regressions, tested on Ubuntu 14.04 on ARMv7 and x86 With gdbserver-{native,extended} / { -marm -mthumb } Also since the target_ops have been changed compilation was tested on affected archs namely : aarch64, arm, bfin, cris, crisv32, m32r, m68k, mips, nios2, ppc, s390, sparc, tic6x, tile, x86, steins. Not tested : sh gdb/gdbserver/ChangeLog: * linux-aarch64-low.c (aarch64_sw_breakpoint_from_kind): New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field. * linux-arm-low.c (arm_breakpoint_kind_from_pc): New function. (arm_sw_breakpoint_from_kind): New function. * linux-bfin-low.c (bfin_sw_breakpoint_from_kind): New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field. * linux-cris-low.c (cris_sw_breakpoint_from_kind): New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field. * linux-crisv32-low.c (cris_sw_breakpoint_from_kind): New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field. * linux-low.c (linux_wait_1): Call breakpoint_kind_from_pc and sw_breakpoint_from_kind to increment the pc. (linux_breakpoint_kind_from_pc): New function. (linux_sw_breakpoint_from_kind): New function. (struct target_ops) <sw_breakpoint_from_kind>: Initialize field. (initialize_low): Call breakpoint_kind_from_pc and sw_breakpoint_from_kind to replace breakpoint_data/len. * linux-low.h (struct linux_target_ops) <breakpoint_kind_from_pc>: New field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Likewise. * linux-m32r-low.c (m32r_sw_breakpoint_from_kind): New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field. * linux-m68k-low.c (m68k_sw_breakpoint_from_kind): New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field. * linux-mips-low.c (mips_sw_breakpoint_from_kind): New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field. * linux-nios2-low.c (nios2_sw_breakpoint_from_kind): New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field. * linux-ppc-low.c (ppc_sw_breakpoint_from_kind): New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field. * linux-s390-low.c (s390_sw_breakpoint_from_kind): New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field. * linux-sh-low.c (sh_sw_breakpoint_from_kind): New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field. * linux-sparc-low.c (sparc_sw_breakpoint_from_kind): New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field. * linux-tic6x-low.c (tic6x_sw_breakpoint_from_kind): New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field. * linux-tile-low.c (tile_sw_breakpoint_from_kind): New function. * linux-x86-low.c (x86_sw_breakpoint_from_kind): New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field. * linux-xtensa-low.c (xtensa_sw_breakpoint_from_kind) New function. (struct linux_target_ops) <breakpoint>: Remove. (struct linux_target_ops) <breakpoint_len>: Remove. (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field. (struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
This commit is contained in:
parent
397dd9a522
commit
dd37334957
|
@ -1,3 +1,94 @@
|
|||
2015-10-21 Antoine Tremblay <antoine.tremblay@ericsson.com>
|
||||
|
||||
* linux-aarch64-low.c (aarch64_sw_breakpoint_from_kind): New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
* linux-arm-low.c (arm_breakpoint_kind_from_pc): New function.
|
||||
(arm_sw_breakpoint_from_kind): New function.
|
||||
* linux-bfin-low.c (bfin_sw_breakpoint_from_kind): New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
* linux-cris-low.c (cris_sw_breakpoint_from_kind): New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
* linux-crisv32-low.c (cris_sw_breakpoint_from_kind): New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
* linux-low.c (linux_wait_1): Call breakpoint_kind_from_pc
|
||||
and sw_breakpoint_from_kind to increment the pc.
|
||||
(linux_breakpoint_kind_from_pc): New function.
|
||||
(linux_sw_breakpoint_from_kind): New function.
|
||||
(struct target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
(initialize_low): Call breakpoint_kind_from_pc and
|
||||
sw_breakpoint_from_kind to replace breakpoint_data/len.
|
||||
* linux-low.h (struct linux_target_ops) <breakpoint_kind_from_pc>:
|
||||
New field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Likewise.
|
||||
* linux-m32r-low.c (m32r_sw_breakpoint_from_kind): New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
* linux-m68k-low.c (m68k_sw_breakpoint_from_kind): New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
* linux-mips-low.c (mips_sw_breakpoint_from_kind): New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
* linux-nios2-low.c (nios2_sw_breakpoint_from_kind): New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
* linux-ppc-low.c (ppc_sw_breakpoint_from_kind): New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
* linux-s390-low.c (s390_sw_breakpoint_from_kind): New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
* linux-sh-low.c (sh_sw_breakpoint_from_kind): New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
* linux-sparc-low.c (sparc_sw_breakpoint_from_kind): New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
* linux-tic6x-low.c (tic6x_sw_breakpoint_from_kind): New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
* linux-tile-low.c (tile_sw_breakpoint_from_kind): New function.
|
||||
* linux-x86-low.c (x86_sw_breakpoint_from_kind): New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
* linux-xtensa-low.c (xtensa_sw_breakpoint_from_kind) New function.
|
||||
(struct linux_target_ops) <breakpoint>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_len>: Remove.
|
||||
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
|
||||
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
|
||||
|
||||
2015-10-21 Antoine Tremblay <antoine.tremblay@ericsson.com>
|
||||
|
||||
* linux-cris-low.c (cris_get_pc): Remove void arg.
|
||||
|
|
|
@ -2931,6 +2931,15 @@ aarch64_supports_range_stepping (void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
aarch64_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = aarch64_breakpoint_len;
|
||||
return aarch64_breakpoint;
|
||||
}
|
||||
|
||||
struct linux_target_ops the_low_target =
|
||||
{
|
||||
aarch64_arch_setup,
|
||||
|
@ -2940,8 +2949,8 @@ struct linux_target_ops the_low_target =
|
|||
NULL, /* fetch_register */
|
||||
aarch64_get_pc,
|
||||
aarch64_set_pc,
|
||||
(const unsigned char *) &aarch64_breakpoint,
|
||||
aarch64_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
aarch64_sw_breakpoint_from_kind,
|
||||
NULL, /* breakpoint_reinsert_addr */
|
||||
0, /* decr_pc_after_break */
|
||||
aarch64_breakpoint_at,
|
||||
|
|
|
@ -913,6 +913,24 @@ arm_regs_info (void)
|
|||
return ®s_info_arm;
|
||||
}
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
arm_sw_breakpoint_from_kind (int kind , int *size)
|
||||
{
|
||||
*size = arm_breakpoint_len;
|
||||
/* Define an ARM-mode breakpoint; we only set breakpoints in the C
|
||||
library, which is most likely to be ARM. If the kernel supports
|
||||
clone events, we will never insert a breakpoint, so even a Thumb
|
||||
C library will work; so will mixing EABI/non-EABI gdbserver and
|
||||
application. */
|
||||
#ifndef __ARM_EABI__
|
||||
return (const gdb_byte *) &arm_breakpoint;
|
||||
#else
|
||||
return (const gdb_byte *) &arm_eabi_breakpoint;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct linux_target_ops the_low_target = {
|
||||
arm_arch_setup,
|
||||
arm_regs_info,
|
||||
|
@ -921,18 +939,8 @@ struct linux_target_ops the_low_target = {
|
|||
NULL, /* fetch_register */
|
||||
arm_get_pc,
|
||||
arm_set_pc,
|
||||
|
||||
/* Define an ARM-mode breakpoint; we only set breakpoints in the C
|
||||
library, which is most likely to be ARM. If the kernel supports
|
||||
clone events, we will never insert a breakpoint, so even a Thumb
|
||||
C library will work; so will mixing EABI/non-EABI gdbserver and
|
||||
application. */
|
||||
#ifndef __ARM_EABI__
|
||||
(const unsigned char *) &arm_breakpoint,
|
||||
#else
|
||||
(const unsigned char *) &arm_eabi_breakpoint,
|
||||
#endif
|
||||
arm_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
arm_sw_breakpoint_from_kind,
|
||||
arm_reinsert_addr,
|
||||
0,
|
||||
arm_breakpoint_at,
|
||||
|
|
|
@ -73,7 +73,16 @@ bfin_set_pc (struct regcache *regcache, CORE_ADDR pc)
|
|||
}
|
||||
|
||||
#define bfin_breakpoint_len 2
|
||||
static const unsigned char bfin_breakpoint[bfin_breakpoint_len] = {0xa1, 0x00};
|
||||
static const gdb_byte bfin_breakpoint[bfin_breakpoint_len] = {0xa1, 0x00};
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
bfin_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = bfin_breakpoint_len;
|
||||
return bfin_breakpoint;
|
||||
}
|
||||
|
||||
static int
|
||||
bfin_breakpoint_at (CORE_ADDR where)
|
||||
|
@ -122,8 +131,8 @@ struct linux_target_ops the_low_target = {
|
|||
NULL, /* fetch_register */
|
||||
bfin_get_pc,
|
||||
bfin_set_pc,
|
||||
bfin_breakpoint,
|
||||
bfin_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
bfin_sw_breakpoint_from_kind,
|
||||
NULL, /* breakpoint_reinsert_addr */
|
||||
2,
|
||||
bfin_breakpoint_at,
|
||||
|
|
|
@ -81,6 +81,15 @@ cris_set_pc (struct regcache *regcache, CORE_ADDR pc)
|
|||
static const unsigned short cris_breakpoint = 0xe938;
|
||||
#define cris_breakpoint_len 2
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
cris_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = cris_breakpoint_len;
|
||||
return (const gdb_byte *) &cris_breakpoint;
|
||||
}
|
||||
|
||||
static int
|
||||
cris_breakpoint_at (CORE_ADDR where)
|
||||
{
|
||||
|
@ -140,8 +149,8 @@ struct linux_target_ops the_low_target = {
|
|||
NULL, /* fetch_register */
|
||||
cris_get_pc,
|
||||
cris_set_pc,
|
||||
(const unsigned char *) &cris_breakpoint,
|
||||
cris_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
cris_sw_breakpoint_from_kind,
|
||||
cris_reinsert_addr,
|
||||
0,
|
||||
cris_breakpoint_at,
|
||||
|
|
|
@ -77,6 +77,15 @@ cris_set_pc (struct regcache *regcache, CORE_ADDR pc)
|
|||
static const unsigned short cris_breakpoint = 0xe938;
|
||||
#define cris_breakpoint_len 2
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
cris_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = cris_breakpoint_len;
|
||||
return (const gdb_byte *) &cris_breakpoint;
|
||||
}
|
||||
|
||||
static int
|
||||
cris_breakpoint_at (CORE_ADDR where)
|
||||
{
|
||||
|
@ -420,8 +429,8 @@ struct linux_target_ops the_low_target = {
|
|||
NULL, /* fetch_register */
|
||||
cris_get_pc,
|
||||
cris_set_pc,
|
||||
(const unsigned char *) &cris_breakpoint,
|
||||
cris_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
cris_sw_breakpoint_from_kind,
|
||||
cris_reinsert_addr,
|
||||
0,
|
||||
cris_breakpoint_at,
|
||||
|
|
|
@ -3012,7 +3012,12 @@ linux_wait_1 (ptid_t ptid,
|
|||
if (!ptid_equal (step_over_bkpt, null_ptid)
|
||||
&& event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT)
|
||||
{
|
||||
unsigned int increment_pc = the_low_target.breakpoint_len;
|
||||
int increment_pc = 0;
|
||||
int breakpoint_kind = 0;
|
||||
CORE_ADDR stop_pc = event_child->stop_pc;
|
||||
|
||||
breakpoint_kind = the_target->breakpoint_kind_from_pc (&stop_pc);
|
||||
the_target->sw_breakpoint_from_kind (breakpoint_kind, &increment_pc);
|
||||
|
||||
if (debug_threads)
|
||||
{
|
||||
|
@ -6932,6 +6937,28 @@ current_lwp_ptid (void)
|
|||
return ptid_of (current_thread);
|
||||
}
|
||||
|
||||
/* Implementation of the target_ops method "breakpoint_kind_from_pc". */
|
||||
|
||||
static int
|
||||
linux_breakpoint_kind_from_pc (CORE_ADDR *pcptr)
|
||||
{
|
||||
if (the_low_target.breakpoint_kind_from_pc != NULL)
|
||||
return (*the_low_target.breakpoint_kind_from_pc) (pcptr);
|
||||
else
|
||||
/* Default breakpoint kind value. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Implementation of the target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
linux_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
gdb_assert (the_low_target.sw_breakpoint_from_kind != NULL);
|
||||
|
||||
return (*the_low_target.sw_breakpoint_from_kind) (kind, size);
|
||||
}
|
||||
|
||||
static struct target_ops linux_target_ops = {
|
||||
linux_create_inferior,
|
||||
linux_arch_setup,
|
||||
|
@ -7026,6 +7053,8 @@ static struct target_ops linux_target_ops = {
|
|||
linux_mntns_open_cloexec,
|
||||
linux_mntns_unlink,
|
||||
linux_mntns_readlink,
|
||||
linux_breakpoint_kind_from_pc,
|
||||
linux_sw_breakpoint_from_kind
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -7053,10 +7082,20 @@ void
|
|||
initialize_low (void)
|
||||
{
|
||||
struct sigaction sigchld_action;
|
||||
int breakpoint_kind = 0;
|
||||
int breakpoint_size = 0;
|
||||
const gdb_byte *breakpoint = NULL;
|
||||
|
||||
memset (&sigchld_action, 0, sizeof (sigchld_action));
|
||||
set_target_ops (&linux_target_ops);
|
||||
set_breakpoint_data (the_low_target.breakpoint,
|
||||
the_low_target.breakpoint_len);
|
||||
|
||||
breakpoint_kind = the_target->breakpoint_kind_from_pc (NULL);
|
||||
breakpoint = the_target->sw_breakpoint_from_kind (breakpoint_kind,
|
||||
&breakpoint_size);
|
||||
|
||||
set_breakpoint_data (breakpoint,
|
||||
breakpoint_size);
|
||||
|
||||
linux_init_signals ();
|
||||
linux_ptrace_init_warnings ();
|
||||
|
||||
|
|
|
@ -141,8 +141,13 @@ struct linux_target_ops
|
|||
|
||||
CORE_ADDR (*get_pc) (struct regcache *regcache);
|
||||
void (*set_pc) (struct regcache *regcache, CORE_ADDR newpc);
|
||||
const unsigned char *breakpoint;
|
||||
int breakpoint_len;
|
||||
|
||||
/* See target.h for details. */
|
||||
int (*breakpoint_kind_from_pc) (CORE_ADDR *pcptr);
|
||||
|
||||
/* See target.h for details. */
|
||||
const gdb_byte *(*sw_breakpoint_from_kind) (int kind, int *size);
|
||||
|
||||
CORE_ADDR (*breakpoint_reinsert_addr) (void);
|
||||
|
||||
int decr_pc_after_break;
|
||||
|
|
|
@ -73,6 +73,15 @@ m32r_set_pc (struct regcache *regcache, CORE_ADDR pc)
|
|||
static const unsigned short m32r_breakpoint = 0x10f1;
|
||||
#define m32r_breakpoint_len 2
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
m32r_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = m32r_breakpoint_len;
|
||||
return (const gdb_byte *) &m32r_breakpoint;
|
||||
}
|
||||
|
||||
static int
|
||||
m32r_breakpoint_at (CORE_ADDR where)
|
||||
{
|
||||
|
@ -120,8 +129,8 @@ struct linux_target_ops the_low_target = {
|
|||
NULL, /* fetch_register */
|
||||
m32r_get_pc,
|
||||
m32r_set_pc,
|
||||
(const unsigned char *) &m32r_breakpoint,
|
||||
m32r_breakpoint_len,
|
||||
NULL, /* breakpoint_from_pc */
|
||||
m32r_sw_breakpoint_from_kind,
|
||||
NULL,
|
||||
0,
|
||||
m32r_breakpoint_at,
|
||||
|
|
|
@ -122,9 +122,18 @@ static struct regset_info m68k_regsets[] = {
|
|||
{ 0, 0, 0, -1, -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static const unsigned char m68k_breakpoint[] = { 0x4E, 0x4F };
|
||||
static const gdb_byte m68k_breakpoint[] = { 0x4E, 0x4F };
|
||||
#define m68k_breakpoint_len 2
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
m68k_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = m68k_breakpoint_len;
|
||||
return m68k_breakpoint;
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
m68k_get_pc (struct regcache *regcache)
|
||||
{
|
||||
|
@ -215,8 +224,8 @@ struct linux_target_ops the_low_target = {
|
|||
NULL, /* fetch_register */
|
||||
m68k_get_pc,
|
||||
m68k_set_pc,
|
||||
m68k_breakpoint,
|
||||
m68k_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
m68k_sw_breakpoint_from_kind,
|
||||
NULL,
|
||||
2,
|
||||
m68k_breakpoint_at,
|
||||
|
|
|
@ -266,6 +266,15 @@ mips_set_pc (struct regcache *regcache, CORE_ADDR pc)
|
|||
static const unsigned int mips_breakpoint = 0x0005000d;
|
||||
#define mips_breakpoint_len 4
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
mips_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = mips_breakpoint_len;
|
||||
return (const gdb_byte *) &mips_breakpoint;
|
||||
}
|
||||
|
||||
/* We only place breakpoints in empty marker functions, and thread locking
|
||||
is outside of the function. So rather than importing software single-step,
|
||||
we can just run until exit. */
|
||||
|
@ -881,8 +890,8 @@ struct linux_target_ops the_low_target = {
|
|||
NULL, /* fetch_register */
|
||||
mips_get_pc,
|
||||
mips_set_pc,
|
||||
(const unsigned char *) &mips_breakpoint,
|
||||
mips_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
mips_sw_breakpoint_from_kind,
|
||||
mips_reinsert_addr,
|
||||
0,
|
||||
mips_breakpoint_at,
|
||||
|
|
|
@ -127,9 +127,23 @@ nios2_set_pc (struct regcache *regcache, CORE_ADDR pc)
|
|||
#define NIOS2_BREAKPOINT 0x003b6ffa
|
||||
#endif
|
||||
|
||||
/* We only register the 4-byte breakpoint, even on R2 targets which also
|
||||
support 2-byte breakpoints. Since there is no supports_z_point_type
|
||||
function provided, gdbserver never inserts software breakpoints itself
|
||||
and instead relies on GDB to insert the breakpoint of the correct length
|
||||
via a memory write. */
|
||||
static const unsigned int nios2_breakpoint = NIOS2_BREAKPOINT;
|
||||
#define nios2_breakpoint_len 4
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
nios2_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = nios2_breakpoint_len;
|
||||
return (const gdb_byte *) &nios2_breakpoint;
|
||||
}
|
||||
|
||||
/* Implement the breakpoint_reinsert_addr linux_target_ops method. */
|
||||
|
||||
static CORE_ADDR
|
||||
|
@ -263,14 +277,8 @@ struct linux_target_ops the_low_target =
|
|||
NULL,
|
||||
nios2_get_pc,
|
||||
nios2_set_pc,
|
||||
|
||||
/* We only register the 4-byte breakpoint, even on R2 targets which also
|
||||
support 2-byte breakpoints. Since there is no supports_z_point_type
|
||||
function provided, gdbserver never inserts software breakpoints itself
|
||||
and instead relies on GDB to insert the breakpoint of the correct length
|
||||
via a memory write. */
|
||||
(const unsigned char *) &nios2_breakpoint,
|
||||
nios2_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
nios2_sw_breakpoint_from_kind,
|
||||
nios2_reinsert_addr,
|
||||
0,
|
||||
nios2_breakpoint_at,
|
||||
|
|
|
@ -486,6 +486,15 @@ ppc_arch_setup (void)
|
|||
static const unsigned int ppc_breakpoint = 0x7d821008;
|
||||
#define ppc_breakpoint_len 4
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
ppc_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = ppc_breakpoint_len;
|
||||
return (const gdb_byte *) &ppc_breakpoint;
|
||||
}
|
||||
|
||||
static int
|
||||
ppc_breakpoint_at (CORE_ADDR where)
|
||||
{
|
||||
|
@ -685,8 +694,8 @@ struct linux_target_ops the_low_target = {
|
|||
NULL, /* fetch_register */
|
||||
ppc_get_pc,
|
||||
ppc_set_pc,
|
||||
(const unsigned char *) &ppc_breakpoint,
|
||||
ppc_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
ppc_sw_breakpoint_from_kind,
|
||||
NULL,
|
||||
0,
|
||||
ppc_breakpoint_at,
|
||||
|
|
|
@ -394,9 +394,18 @@ static struct regset_info s390_regsets[] = {
|
|||
};
|
||||
|
||||
|
||||
static const unsigned char s390_breakpoint[] = { 0, 1 };
|
||||
static const gdb_byte s390_breakpoint[] = { 0, 1 };
|
||||
#define s390_breakpoint_len 2
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
s390_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = s390_breakpoint_len;
|
||||
return s390_breakpoint;
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
s390_get_pc (struct regcache *regcache)
|
||||
{
|
||||
|
@ -665,8 +674,8 @@ struct linux_target_ops the_low_target = {
|
|||
NULL, /* fetch_register */
|
||||
s390_get_pc,
|
||||
s390_set_pc,
|
||||
s390_breakpoint,
|
||||
s390_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
s390_sw_breakpoint_from_kind,
|
||||
NULL,
|
||||
s390_breakpoint_len,
|
||||
s390_breakpoint_at,
|
||||
|
|
|
@ -77,6 +77,15 @@ sh_set_pc (struct regcache *regcache, CORE_ADDR pc)
|
|||
static const unsigned short sh_breakpoint = 0xc3c3;
|
||||
#define sh_breakpoint_len 2
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
sh_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = sh_breakpoint_len;
|
||||
return (const gdb_byte *) &sh_breakpoint;
|
||||
}
|
||||
|
||||
static int
|
||||
sh_breakpoint_at (CORE_ADDR where)
|
||||
{
|
||||
|
@ -148,8 +157,8 @@ struct linux_target_ops the_low_target = {
|
|||
NULL, /* fetch_register */
|
||||
sh_get_pc,
|
||||
sh_set_pc,
|
||||
(const unsigned char *) &sh_breakpoint,
|
||||
sh_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
sh_sw_breakpoint_from_kind,
|
||||
NULL,
|
||||
0,
|
||||
sh_breakpoint_at,
|
||||
|
|
|
@ -235,11 +235,19 @@ sparc_get_pc (struct regcache *regcache)
|
|||
return pc;
|
||||
}
|
||||
|
||||
static const unsigned char sparc_breakpoint[INSN_SIZE] = {
|
||||
static const gdb_byte sparc_breakpoint[INSN_SIZE] = {
|
||||
0x91, 0xd0, 0x20, 0x01
|
||||
};
|
||||
#define sparc_breakpoint_len INSN_SIZE
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const unsigned char *
|
||||
sparc_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = sparc_breakpoint_len;
|
||||
return sparc_breakpoint;
|
||||
}
|
||||
|
||||
static int
|
||||
sparc_breakpoint_at (CORE_ADDR where)
|
||||
|
@ -323,8 +331,8 @@ struct linux_target_ops the_low_target = {
|
|||
sparc_get_pc,
|
||||
/* No sparc_set_pc is needed. */
|
||||
NULL,
|
||||
(const unsigned char *) sparc_breakpoint,
|
||||
sparc_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
sparc_sw_breakpoint_from_kind,
|
||||
sparc_reinsert_addr,
|
||||
0,
|
||||
sparc_breakpoint_at,
|
||||
|
|
|
@ -171,6 +171,16 @@ extern struct linux_target_ops the_low_target;
|
|||
|
||||
static int *tic6x_regmap;
|
||||
static unsigned int tic6x_breakpoint;
|
||||
#define tic6x_breakpoint_len 4
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
tic6x_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = tic6x_breakpoint_len;
|
||||
return (const gdb_byte *) &tic6x_breakpoint;
|
||||
}
|
||||
|
||||
/* Forward definition. */
|
||||
static struct usrregs_info tic6x_usrregs_info;
|
||||
|
@ -247,8 +257,6 @@ tic6x_set_pc (struct regcache *regcache, CORE_ADDR pc)
|
|||
supply_register_by_name (regcache, "PC", newpc.buf);
|
||||
}
|
||||
|
||||
#define tic6x_breakpoint_len 4
|
||||
|
||||
static int
|
||||
tic6x_breakpoint_at (CORE_ADDR where)
|
||||
{
|
||||
|
@ -367,8 +375,8 @@ struct linux_target_ops the_low_target = {
|
|||
NULL, /* fetch_register */
|
||||
tic6x_get_pc,
|
||||
tic6x_set_pc,
|
||||
(const unsigned char *) &tic6x_breakpoint,
|
||||
tic6x_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
tic6x_sw_breakpoint_from_kind,
|
||||
NULL,
|
||||
0,
|
||||
tic6x_breakpoint_at,
|
||||
|
|
|
@ -88,6 +88,15 @@ tile_set_pc (struct regcache *regcache, CORE_ADDR pc)
|
|||
static uint64_t tile_breakpoint = 0x400b3cae70166000ULL;
|
||||
#define tile_breakpoint_len 8
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
tile_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = tile_breakpoint_len;
|
||||
return (const gdb_byte *) &tile_breakpoint;
|
||||
}
|
||||
|
||||
static int
|
||||
tile_breakpoint_at (CORE_ADDR where)
|
||||
{
|
||||
|
@ -182,8 +191,8 @@ struct linux_target_ops the_low_target =
|
|||
NULL,
|
||||
tile_get_pc,
|
||||
tile_set_pc,
|
||||
(const unsigned char *) &tile_breakpoint,
|
||||
tile_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
tile_sw_breakpoint_from_kind,
|
||||
NULL,
|
||||
0,
|
||||
tile_breakpoint_at,
|
||||
|
|
|
@ -502,7 +502,7 @@ x86_set_pc (struct regcache *regcache, CORE_ADDR pc)
|
|||
}
|
||||
}
|
||||
|
||||
static const unsigned char x86_breakpoint[] = { 0xCC };
|
||||
static const gdb_byte x86_breakpoint[] = { 0xCC };
|
||||
#define x86_breakpoint_len 1
|
||||
|
||||
static int
|
||||
|
@ -3243,6 +3243,15 @@ x86_emit_ops (void)
|
|||
return &i386_emit_ops;
|
||||
}
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
x86_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = x86_breakpoint_len;
|
||||
return x86_breakpoint;
|
||||
}
|
||||
|
||||
static int
|
||||
x86_supports_range_stepping (void)
|
||||
{
|
||||
|
@ -3261,8 +3270,8 @@ struct linux_target_ops the_low_target =
|
|||
NULL, /* fetch_register */
|
||||
x86_get_pc,
|
||||
x86_set_pc,
|
||||
x86_breakpoint,
|
||||
x86_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
x86_sw_breakpoint_from_kind,
|
||||
NULL,
|
||||
1,
|
||||
x86_breakpoint_at,
|
||||
|
|
|
@ -151,9 +151,18 @@ static struct regset_info xtensa_regsets[] = {
|
|||
#define XTENSA_BREAKPOINT {0x2d,0xf0}
|
||||
#endif
|
||||
|
||||
static const unsigned char xtensa_breakpoint[] = XTENSA_BREAKPOINT;
|
||||
static const gdb_byte xtensa_breakpoint[] = XTENSA_BREAKPOINT;
|
||||
#define xtensa_breakpoint_len 2
|
||||
|
||||
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
|
||||
|
||||
static const gdb_byte *
|
||||
xtensa_sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
*size = xtensa_breakpoint_len;
|
||||
return xtensa_breakpoint;
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
xtensa_get_pc (struct regcache *regcache)
|
||||
{
|
||||
|
@ -234,8 +243,8 @@ struct linux_target_ops the_low_target = {
|
|||
NULL, /* fetch_register */
|
||||
xtensa_get_pc,
|
||||
xtensa_set_pc,
|
||||
xtensa_breakpoint,
|
||||
xtensa_breakpoint_len,
|
||||
NULL, /* breakpoint_kind_from_pc */
|
||||
xtensa_sw_breakpoint_from_kind,
|
||||
NULL,
|
||||
0,
|
||||
xtensa_breakpoint_at,
|
||||
|
|
|
@ -441,6 +441,16 @@ struct target_ops
|
|||
readlink(2). */
|
||||
ssize_t (*multifs_readlink) (int pid, const char *filename,
|
||||
char *buf, size_t bufsiz);
|
||||
|
||||
/* Return the breakpoint kind for this target based on PC. The PCPTR is
|
||||
adjusted to the real memory location in case a flag (e.g., the Thumb bit on
|
||||
ARM) was present in the PC. */
|
||||
int (*breakpoint_kind_from_pc) (CORE_ADDR *pcptr);
|
||||
|
||||
/* Return the software breakpoint from KIND. KIND can have target
|
||||
specific meaning like the Z0 kind parameter.
|
||||
SIZE is set to the software breakpoint's length in memory. */
|
||||
const gdb_byte *(*sw_breakpoint_from_kind) (int kind, int *size);
|
||||
};
|
||||
|
||||
extern struct target_ops *the_target;
|
||||
|
|
Loading…
Reference in New Issue