summaryrefslogtreecommitdiff
path: root/gdb/mips-linux-tdep.c
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2012-05-22 17:12:03 +0000
committerMaciej W. Rozycki <macro@linux-mips.org>2012-05-22 17:12:03 +0000
commita846c7e1faadf34e404eb9789d6ecf848516d737 (patch)
tree0d38a069fe8e6f1cadad949447350b56227e8042 /gdb/mips-linux-tdep.c
parentda3d5ed1ebdcc72fdbf09ce10a15e9da9f47d2ae (diff)
downloadgdb-a846c7e1faadf34e404eb9789d6ecf848516d737.tar.gz
* NEWS: Add MIPS/Linux DSP support.
* mips-linux-tdep.c: Document post-2.6.12 o32 sigcontext layout. (SIGCONTEXT_DSPCTL): New macro. (SIGCONTEXT_HI1, SIGCONTEXT_LO1): Likewise. (SIGCONTEXT_HI2, SIGCONTEXT_LO2): Likewise. (SIGCONTEXT_HI3, SIGCONTEXT_LO3): Likewise. (N64_SIGCONTEXT_HI1, N64_SIGCONTEXT_HI2): Likewise. (N64_SIGCONTEXT_HI3): Likewise. (N64_SIGCONTEXT_LO1, N64_SIGCONTEXT_LO2): Likewise. (N64_SIGCONTEXT_LO3): Likewise. (N64_SIGCONTEXT_DSPCTL): Likewise. (N64_SIGCONTEXT_FPCSR): Clarify definition. (mips_linux_o32_sigframe_init): Handle DSP registers. (mips_linux_n32n64_sigframe_init): Likewise.
Diffstat (limited to 'gdb/mips-linux-tdep.c')
-rw-r--r--gdb/mips-linux-tdep.c112
1 files changed, 105 insertions, 7 deletions
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
index 6e24a8e5532..c6512af7b1b 100644
--- a/gdb/mips-linux-tdep.c
+++ b/gdb/mips-linux-tdep.c
@@ -869,6 +869,8 @@ static const struct tramp_frame mips_linux_n64_rt_sigframe = {
sigset_t sf_mask;
};
+ Pre-2.6.12 sigcontext:
+
struct sigcontext {
unsigned int sc_regmask; [Unused]
unsigned int sc_status;
@@ -890,6 +892,30 @@ static const struct tramp_frame mips_linux_n64_rt_sigframe = {
unsigned long sc_sigset[4]; [kernel's sigset_t]
};
+ Post-2.6.12 sigcontext (SmartMIPS/DSP support added):
+
+ struct sigcontext {
+ unsigned int sc_regmask; [Unused]
+ unsigned int sc_status; [Unused]
+ unsigned long long sc_pc;
+ unsigned long long sc_regs[32];
+ unsigned long long sc_fpregs[32];
+ unsigned int sc_acx;
+ unsigned int sc_fpc_csr;
+ unsigned int sc_fpc_eir; [Unused]
+ unsigned int sc_used_math;
+ unsigned int sc_dsp;
+ [Alignment hole of four bytes]
+ unsigned long long sc_mdhi;
+ unsigned long long sc_mdlo;
+ unsigned long sc_hi1;
+ unsigned long sc_lo1;
+ unsigned long sc_hi2;
+ unsigned long sc_lo2;
+ unsigned long sc_hi3;
+ unsigned long sc_lo3;
+ };
+
The RT signal frames look like this:
struct rt_sigframe {
@@ -922,10 +948,17 @@ static const struct tramp_frame mips_linux_n64_rt_sigframe = {
#define SIGCONTEXT_REGS (2 * 8)
#define SIGCONTEXT_FPREGS (34 * 8)
#define SIGCONTEXT_FPCSR (66 * 8 + 4)
+#define SIGCONTEXT_DSPCTL (68 * 8 + 0)
#define SIGCONTEXT_HI (69 * 8)
#define SIGCONTEXT_LO (70 * 8)
#define SIGCONTEXT_CAUSE (71 * 8 + 0)
#define SIGCONTEXT_BADVADDR (71 * 8 + 4)
+#define SIGCONTEXT_HI1 (71 * 8 + 0)
+#define SIGCONTEXT_LO1 (71 * 8 + 4)
+#define SIGCONTEXT_HI2 (72 * 8 + 0)
+#define SIGCONTEXT_LO2 (72 * 8 + 4)
+#define SIGCONTEXT_HI3 (73 * 8 + 0)
+#define SIGCONTEXT_LO3 (73 * 8 + 4)
#define SIGCONTEXT_REG_SIZE 8
@@ -1000,18 +1033,49 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self,
regs->fp_control_status
+ gdbarch_num_regs (gdbarch),
sigcontext_base + SIGCONTEXT_FPCSR);
+
+ if (regs->dspctl != -1)
+ trad_frame_set_reg_addr (this_cache,
+ regs->dspctl + gdbarch_num_regs (gdbarch),
+ sigcontext_base + SIGCONTEXT_DSPCTL);
+
trad_frame_set_reg_addr (this_cache,
regs->hi + gdbarch_num_regs (gdbarch),
regs_base + SIGCONTEXT_HI);
trad_frame_set_reg_addr (this_cache,
regs->lo + gdbarch_num_regs (gdbarch),
regs_base + SIGCONTEXT_LO);
- trad_frame_set_reg_addr (this_cache,
- regs->cause + gdbarch_num_regs (gdbarch),
- sigcontext_base + SIGCONTEXT_CAUSE);
- trad_frame_set_reg_addr (this_cache,
- regs->badvaddr + gdbarch_num_regs (gdbarch),
- sigcontext_base + SIGCONTEXT_BADVADDR);
+
+ if (regs->dspacc != -1)
+ {
+ trad_frame_set_reg_addr (this_cache,
+ regs->dspacc + 0 + gdbarch_num_regs (gdbarch),
+ sigcontext_base + SIGCONTEXT_HI1);
+ trad_frame_set_reg_addr (this_cache,
+ regs->dspacc + 1 + gdbarch_num_regs (gdbarch),
+ sigcontext_base + SIGCONTEXT_LO1);
+ trad_frame_set_reg_addr (this_cache,
+ regs->dspacc + 2 + gdbarch_num_regs (gdbarch),
+ sigcontext_base + SIGCONTEXT_HI2);
+ trad_frame_set_reg_addr (this_cache,
+ regs->dspacc + 3 + gdbarch_num_regs (gdbarch),
+ sigcontext_base + SIGCONTEXT_LO2);
+ trad_frame_set_reg_addr (this_cache,
+ regs->dspacc + 4 + gdbarch_num_regs (gdbarch),
+ sigcontext_base + SIGCONTEXT_HI3);
+ trad_frame_set_reg_addr (this_cache,
+ regs->dspacc + 5 + gdbarch_num_regs (gdbarch),
+ sigcontext_base + SIGCONTEXT_LO3);
+ }
+ else
+ {
+ trad_frame_set_reg_addr (this_cache,
+ regs->cause + gdbarch_num_regs (gdbarch),
+ sigcontext_base + SIGCONTEXT_CAUSE);
+ trad_frame_set_reg_addr (this_cache,
+ regs->badvaddr + gdbarch_num_regs (gdbarch),
+ sigcontext_base + SIGCONTEXT_BADVADDR);
+ }
/* Choice of the bottom of the sigframe is somewhat arbitrary. */
trad_frame_set_id (this_cache, frame_id_build (frame_sp, func));
@@ -1089,9 +1153,16 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self,
#define N64_SIGCONTEXT_REGS (0 * 8)
#define N64_SIGCONTEXT_FPREGS (32 * 8)
#define N64_SIGCONTEXT_HI (64 * 8)
+#define N64_SIGCONTEXT_HI1 (65 * 8)
+#define N64_SIGCONTEXT_HI2 (66 * 8)
+#define N64_SIGCONTEXT_HI3 (67 * 8)
#define N64_SIGCONTEXT_LO (68 * 8)
+#define N64_SIGCONTEXT_LO1 (69 * 8)
+#define N64_SIGCONTEXT_LO2 (70 * 8)
+#define N64_SIGCONTEXT_LO3 (71 * 8)
#define N64_SIGCONTEXT_PC (72 * 8)
-#define N64_SIGCONTEXT_FPCSR (73 * 8)
+#define N64_SIGCONTEXT_FPCSR (73 * 8 + 0)
+#define N64_SIGCONTEXT_DSPCTL (74 * 8 + 0)
#define N64_SIGCONTEXT_REG_SIZE 8
@@ -1140,6 +1211,7 @@ mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
regs->fp_control_status
+ gdbarch_num_regs (gdbarch),
sigcontext_base + N64_SIGCONTEXT_FPCSR);
+
trad_frame_set_reg_addr (this_cache,
regs->hi + gdbarch_num_regs (gdbarch),
sigcontext_base + N64_SIGCONTEXT_HI);
@@ -1147,6 +1219,32 @@ mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
regs->lo + gdbarch_num_regs (gdbarch),
sigcontext_base + N64_SIGCONTEXT_LO);
+ if (regs->dspacc != -1)
+ {
+ trad_frame_set_reg_addr (this_cache,
+ regs->dspacc + 0 + gdbarch_num_regs (gdbarch),
+ sigcontext_base + N64_SIGCONTEXT_HI1);
+ trad_frame_set_reg_addr (this_cache,
+ regs->dspacc + 1 + gdbarch_num_regs (gdbarch),
+ sigcontext_base + N64_SIGCONTEXT_LO1);
+ trad_frame_set_reg_addr (this_cache,
+ regs->dspacc + 2 + gdbarch_num_regs (gdbarch),
+ sigcontext_base + N64_SIGCONTEXT_HI2);
+ trad_frame_set_reg_addr (this_cache,
+ regs->dspacc + 3 + gdbarch_num_regs (gdbarch),
+ sigcontext_base + N64_SIGCONTEXT_LO2);
+ trad_frame_set_reg_addr (this_cache,
+ regs->dspacc + 4 + gdbarch_num_regs (gdbarch),
+ sigcontext_base + N64_SIGCONTEXT_HI3);
+ trad_frame_set_reg_addr (this_cache,
+ regs->dspacc + 5 + gdbarch_num_regs (gdbarch),
+ sigcontext_base + N64_SIGCONTEXT_LO3);
+ }
+ if (regs->dspctl != -1)
+ trad_frame_set_reg_addr (this_cache,
+ regs->dspctl + gdbarch_num_regs (gdbarch),
+ sigcontext_base + N64_SIGCONTEXT_DSPCTL);
+
/* Choice of the bottom of the sigframe is somewhat arbitrary. */
trad_frame_set_id (this_cache, frame_id_build (frame_sp, func));
}