Remove mips dependency on alpha.
[jlayton/glibc.git] / ports / sysdeps / unix / sysv / linux / m68k / register-dump.h
1 /* Dump registers.
2    Copyright (C) 1998-2014 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Andreas Schwab <schwab@gnu.org>.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library.  If not, see
18    <http://www.gnu.org/licenses/>.  */
19
20 #include <stddef.h>
21 #include <sys/uio.h>
22 #include <_itoa.h>
23
24 /* We will print the register dump in this format:
25
26   D0: XXXXXXXX   D1: XXXXXXXX   D2: XXXXXXXX   D3: XXXXXXXX
27   D4: XXXXXXXX   D5: XXXXXXXX   D6: XXXXXXXX   D7: XXXXXXXX
28   A0: XXXXXXXX   A1: XXXXXXXX   A2: XXXXXXXX   A3: XXXXXXXX
29   A4: XXXXXXXX   A5: XXXXXXXX   A6: XXXXXXXX   A7: XXXXXXXX
30   PC: XXXXXXXX   SR: XXXX
31
32   OldMask: XXXXXXXX  Vector: XXXX
33
34   FP0: XXXXXXXXXXXXXXXXXXXXXXXX   FP1: XXXXXXXXXXXXXXXXXXXXXXXX
35   FP2: XXXXXXXXXXXXXXXXXXXXXXXX   FP3: XXXXXXXXXXXXXXXXXXXXXXXX
36   FP4: XXXXXXXXXXXXXXXXXXXXXXXX   FP5: XXXXXXXXXXXXXXXXXXXXXXXX
37   FP6: XXXXXXXXXXXXXXXXXXXXXXXX   FP7: XXXXXXXXXXXXXXXXXXXXXXXX
38   FPCR: XXXXXXXX   FPSR: XXXXXXXX   FPIAR: XXXXXXXX
39
40 */
41
42 /* Linux saves only the call-clobbered registers in the sigcontext.  We
43    need to use a trampoline that saves the rest so that the C code can
44    access them.  We use the sc_fpstate field, since the handler is not
45    supposed to return anyway, thus it doesn't matter that it's clobbered.  */
46
47 /* static */ void catch_segfault (int, int, struct sigcontext *);
48
49 /* Dummy function so that we can use asm with arguments.  */
50 static void __attribute_used__
51 __dummy__ (void)
52 {
53   asm ("\n\
54 catch_segfault:\n\
55         move.l 12(%%sp),%%a0\n\
56         lea %c0(%%a0),%%a0\n\
57         /* Clear the first 4 bytes to make it a null fp state, just\n\
58            in case the handler does return.  */\n\
59         clr.l (%%a0)+\n\
60         movem.l %%d2-%%d7/%%a2-%%a6,(%%a0)\n"
61 #ifndef __mcoldfire__
62        "fmovem.x %%fp2-%%fp7,11*4(%%a0)\n"
63 #elif defined __mcffpu__
64        "fmovem.d %%fp2-%%fp7,11*4(%%a0)\n"
65 #endif
66        "jra real_catch_segfault"
67        : : "n" (offsetof (struct sigcontext, sc_fpstate)));
68 }
69 #define catch_segfault(a,b) \
70   __attribute_used__ real_catch_segfault(a,b)
71
72 static void
73 hexvalue (unsigned long int value, char *buf, size_t len)
74 {
75   char *cp = _itoa_word (value, buf + len, 16, 0);
76   while (cp > buf)
77     *--cp = '0';
78 }
79
80 static void
81 register_dump (int fd, struct sigcontext *ctx)
82 {
83   char regs[20][8];
84   char fpregs[11][24];
85   struct iovec iov[63], *next_iov = iov;
86   unsigned long *p = (unsigned long *) ctx->sc_fpstate + 1;
87   unsigned long *pfp = (unsigned long *) ctx->sc_fpregs;
88   int i, j, fpreg_size;
89
90 #define ADD_STRING(str) \
91   next_iov->iov_base = (char *) (str); \
92   next_iov->iov_len = strlen (str); \
93   ++next_iov
94 #define ADD_MEM(str, len) \
95   next_iov->iov_base = (str); \
96   next_iov->iov_len = (len); \
97   ++next_iov
98
99 #ifdef __mcoldfire__
100   fpreg_size = 16;
101 #else
102   fpreg_size = 24;
103 #endif
104
105   /* Generate strings of register contents.  */
106   hexvalue (ctx->sc_d0, regs[0], 8);
107   hexvalue (ctx->sc_d1, regs[1], 8);
108   hexvalue (*p++, regs[2], 8);
109   hexvalue (*p++, regs[3], 8);
110   hexvalue (*p++, regs[4], 8);
111   hexvalue (*p++, regs[5], 8);
112   hexvalue (*p++, regs[6], 8);
113   hexvalue (*p++, regs[7], 8);
114   hexvalue (ctx->sc_a0, regs[8], 8);
115   hexvalue (ctx->sc_a1, regs[9], 8);
116   hexvalue (*p++, regs[10], 8);
117   hexvalue (*p++, regs[11], 8);
118   hexvalue (*p++, regs[12], 8);
119   hexvalue (*p++, regs[13], 8);
120   hexvalue (*p++, regs[14], 8);
121   hexvalue (ctx->sc_usp, regs[15], 8);
122   hexvalue (ctx->sc_pc, regs[16], 8);
123   hexvalue (ctx->sc_sr, regs[17], 4);
124   hexvalue (ctx->sc_mask, regs[18], 8);
125   hexvalue (ctx->sc_formatvec & 0xfff, regs[19], 4);
126   for (i = 0; i < 2; i++)
127     for (j = 0; j < fpreg_size; j += 8)
128       hexvalue (*pfp++, fpregs[i] + j, 8);
129   for (i = 2; i < 8; i++)
130     for (j = 0; j < fpreg_size; j += 8)
131       hexvalue (*p++, fpregs[i] + j, 8);
132   hexvalue (ctx->sc_fpcntl[0], fpregs[8], 8);
133   hexvalue (ctx->sc_fpcntl[1], fpregs[9], 8);
134   hexvalue (ctx->sc_fpcntl[2], fpregs[10], 8);
135
136   /* Generate the output.  */
137   ADD_STRING ("Register dump:\n\n  D0: ");
138   ADD_MEM (regs[0], 8);
139   ADD_STRING ("  D1: ");
140   ADD_MEM (regs[1], 8);
141   ADD_STRING ("  D2: ");
142   ADD_MEM (regs[2], 8);
143   ADD_STRING ("  D3: ");
144   ADD_MEM (regs[3], 8);
145   ADD_STRING ("\n  D4: ");
146   ADD_MEM (regs[4], 8);
147   ADD_STRING ("  D5: ");
148   ADD_MEM (regs[5], 8);
149   ADD_STRING ("  D6: ");
150   ADD_MEM (regs[6], 8);
151   ADD_STRING ("  D7: ");
152   ADD_MEM (regs[7], 8);
153   ADD_STRING ("\n  A0: ");
154   ADD_MEM (regs[8], 8);
155   ADD_STRING ("  A1: ");
156   ADD_MEM (regs[9], 8);
157   ADD_STRING ("  A2: ");
158   ADD_MEM (regs[10], 8);
159   ADD_STRING ("  A3: ");
160   ADD_MEM (regs[11], 8);
161   ADD_STRING ("\n  A4: ");
162   ADD_MEM (regs[12], 8);
163   ADD_STRING ("  A5: ");
164   ADD_MEM (regs[13], 8);
165   ADD_STRING ("  A6: ");
166   ADD_MEM (regs[14], 8);
167   ADD_STRING ("  A7: ");
168   ADD_MEM (regs[15], 8);
169   ADD_STRING ("\n  PC: ");
170   ADD_MEM (regs[16], 8);
171   ADD_STRING ("  SR: ");
172   ADD_MEM (regs[17], 4);
173
174   ADD_STRING ("\n\n  OldMask: ");
175   ADD_MEM (regs[18], 8);
176   ADD_STRING ("  Vector: ");
177   ADD_MEM (regs[19], 4);
178
179   ADD_STRING ("\n\n  FP0: ");
180   ADD_MEM (fpregs[0], fpreg_size);
181   ADD_STRING ("  FP1: ");
182   ADD_MEM (fpregs[1], fpreg_size);
183   ADD_STRING ("\n  FP2: ");
184   ADD_MEM (fpregs[2], fpreg_size);
185   ADD_STRING ("  FP3: ");
186   ADD_MEM (fpregs[3], fpreg_size);
187   ADD_STRING ("\n  FP4: ");
188   ADD_MEM (fpregs[4], fpreg_size);
189   ADD_STRING ("  FP5: ");
190   ADD_MEM (fpregs[5], fpreg_size);
191   ADD_STRING ("\n  FP6: ");
192   ADD_MEM (fpregs[6], fpreg_size);
193   ADD_STRING ("  FP7: ");
194   ADD_MEM (fpregs[7], fpreg_size);
195   ADD_STRING ("\n  FPCR: ");
196   ADD_MEM (fpregs[8], 8);
197   ADD_STRING ("  FPSR: ");
198   ADD_MEM (fpregs[9], 8);
199   ADD_STRING ("  FPIAR: ");
200   ADD_MEM (fpregs[10], 8);
201   ADD_STRING ("\n");
202
203   /* Write the stuff out.  */
204   writev (fd, iov, next_iov - iov);
205 }
206
207 #define REGISTER_DUMP register_dump (fd, ctx)