| Index: gdb/gdbserver/linux-mips-low.c
|
| diff --git a/gdb/gdbserver/linux-mips-low.c b/gdb/gdbserver/linux-mips-low.c
|
| index 8baf1b0ce6c1bb18e5653e4aae29717cbfd9f1a6..8e37298d118ddef4765590116a047d4b1bea8b8d 100644
|
| --- a/gdb/gdbserver/linux-mips-low.c
|
| +++ b/gdb/gdbserver/linux-mips-low.c
|
| @@ -27,8 +27,17 @@
|
|
|
| /* Defined in auto-generated file mips-linux.c. */
|
| void init_registers_mips_linux (void);
|
| +/* Defined in auto-generated file mips-dsp-linux.c. */
|
| +void init_registers_mips_dsp_linux (void);
|
| /* Defined in auto-generated file mips64-linux.c. */
|
| void init_registers_mips64_linux (void);
|
| +/* Defined in auto-generated file mips64-dsp-linux.c. */
|
| +void init_registers_mips64_dsp_linux (void);
|
| +
|
| +#ifdef __mips64
|
| +#define init_registers_mips_linux init_registers_mips64_linux
|
| +#define init_registers_mips_dsp_linux init_registers_mips64_dsp_linux
|
| +#endif
|
|
|
| #ifndef PTRACE_GET_THREAD_AREA
|
| #define PTRACE_GET_THREAD_AREA 25
|
| @@ -39,9 +48,15 @@ void init_registers_mips64_linux (void);
|
| #endif
|
|
|
| #define mips_num_regs 73
|
| +#define mips_dsp_num_regs 80
|
|
|
| #include <asm/ptrace.h>
|
|
|
| +#ifndef DSP_BASE
|
| +#define DSP_BASE 71
|
| +#define DSP_CONTROL 77
|
| +#endif
|
| +
|
| union mips_register
|
| {
|
| unsigned char buf[8];
|
| @@ -53,27 +68,84 @@ union mips_register
|
|
|
| /* Return the ptrace ``address'' of register REGNO. */
|
|
|
| -static int mips_regmap[] = {
|
| - -1, 1, 2, 3, 4, 5, 6, 7,
|
| - 8, 9, 10, 11, 12, 13, 14, 15,
|
| - 16, 17, 18, 19, 20, 21, 22, 23,
|
| - 24, 25, 26, 27, 28, 29, 30, 31,
|
| +#define mips_base_regs \
|
| + -1, 1, 2, 3, 4, 5, 6, 7, \
|
| + 8, 9, 10, 11, 12, 13, 14, 15, \
|
| + 16, 17, 18, 19, 20, 21, 22, 23, \
|
| + 24, 25, 26, 27, 28, 29, 30, 31, \
|
| + \
|
| + -1, MMLO, MMHI, BADVADDR, CAUSE, PC, \
|
| + \
|
| + FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3, \
|
| + FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7, \
|
| + FPR_BASE + 8, FPR_BASE + 9, FPR_BASE + 10, FPR_BASE + 11, \
|
| + FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15, \
|
| + FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19, \
|
| + FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23, \
|
| + FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27, \
|
| + FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31, \
|
| + FPC_CSR, FPC_EIR
|
| +
|
| +#define mips_dsp_regs \
|
| + DSP_BASE, DSP_BASE + 1, DSP_BASE + 2, DSP_BASE + 3, \
|
| + DSP_BASE + 4, DSP_BASE + 5, \
|
| + DSP_CONTROL
|
| +
|
| +static int mips_regmap[mips_num_regs] = {
|
| + mips_base_regs,
|
| + 0
|
| +};
|
|
|
| - -1, MMLO, MMHI, BADVADDR, CAUSE, PC,
|
| +static int mips_dsp_regmap[mips_dsp_num_regs] = {
|
| + mips_base_regs,
|
| + mips_dsp_regs,
|
| + 0
|
| +};
|
|
|
| - FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3,
|
| - FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7,
|
| - FPR_BASE + 8, FPR_BASE + 8, FPR_BASE + 10, FPR_BASE + 11,
|
| - FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15,
|
| - FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19,
|
| - FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23,
|
| - FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27,
|
| - FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31,
|
| - FPC_CSR, FPC_EIR,
|
| +/* DSP registers are not in any regset and can only be accessed
|
| + individually. */
|
|
|
| - 0
|
| +static unsigned char mips_dsp_regset_bitmap[(mips_dsp_num_regs + 7) / 8] = {
|
| + 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x80
|
| };
|
|
|
| +/* Try peeking at an arbitrarily chosen DSP register and pick the available
|
| + user register set accordingly. */
|
| +
|
| +static void
|
| +mips_arch_setup (void)
|
| +{
|
| + static void (*init_registers) (void);
|
| +
|
| + gdb_assert (current_inferior);
|
| +
|
| + if (init_registers == NULL)
|
| + {
|
| + int pid = lwpid_of (get_thread_lwp (current_inferior));
|
| +
|
| + ptrace (PTRACE_PEEKUSER, pid, DSP_CONTROL, 0);
|
| + switch (errno)
|
| + {
|
| + case 0:
|
| + the_low_target.num_regs = mips_dsp_num_regs;
|
| + the_low_target.regmap = mips_dsp_regmap;
|
| + the_low_target.regset_bitmap = mips_dsp_regset_bitmap;
|
| + init_registers = init_registers_mips_dsp_linux;
|
| + break;
|
| + case EIO:
|
| + the_low_target.num_regs = mips_num_regs;
|
| + the_low_target.regmap = mips_regmap;
|
| + the_low_target.regset_bitmap = NULL;
|
| + init_registers = init_registers_mips_linux;
|
| + break;
|
| + default:
|
| + perror_with_name ("ptrace");
|
| + break;
|
| + }
|
| + }
|
| + init_registers ();
|
| +}
|
| +
|
| /* From mips-linux-nat.c. */
|
|
|
| /* Pseudo registers can not be read. ptrace does not provide a way to
|
| @@ -84,7 +156,7 @@ static int mips_regmap[] = {
|
| static int
|
| mips_cannot_fetch_register (int regno)
|
| {
|
| - if (mips_regmap[regno] == -1)
|
| + if (the_low_target.regmap[regno] == -1)
|
| return 1;
|
|
|
| if (find_regno ("r0") == regno)
|
| @@ -96,7 +168,7 @@ mips_cannot_fetch_register (int regno)
|
| static int
|
| mips_cannot_store_register (int regno)
|
| {
|
| - if (mips_regmap[regno] == -1)
|
| + if (the_low_target.regmap[regno] == -1)
|
| return 1;
|
|
|
| if (find_regno ("r0") == regno)
|
| @@ -352,15 +424,13 @@ struct regset_info target_regsets[] = {
|
| };
|
|
|
| struct linux_target_ops the_low_target = {
|
| -#ifdef __mips64
|
| - init_registers_mips64_linux,
|
| -#else
|
| - init_registers_mips_linux,
|
| -#endif
|
| - mips_num_regs,
|
| - mips_regmap,
|
| + mips_arch_setup,
|
| + -1,
|
| + NULL,
|
| + NULL,
|
| mips_cannot_fetch_register,
|
| mips_cannot_store_register,
|
| + NULL, /* fetch_register */
|
| mips_get_pc,
|
| mips_set_pc,
|
| (const unsigned char *) &mips_breakpoint,
|
|
|