chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / ports / sysdeps / unix / sysv / linux / m68k / register-dump.h
1 /* Dump registers.
2    Copyright (C) 1998, 2002, 2004 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, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 #include <stddef.h>
22 #include <sys/uio.h>
23 #include <stdio-common/_itoa.h>
24
25 /* We will print the register dump in this format:
26
27   D0: XXXXXXXX   D1: XXXXXXXX   D2: XXXXXXXX   D3: XXXXXXXX
28   D4: XXXXXXXX   D5: XXXXXXXX   D6: XXXXXXXX   D7: XXXXXXXX
29   A0: XXXXXXXX   A1: XXXXXXXX   A2: XXXXXXXX   A3: XXXXXXXX
30   A4: XXXXXXXX   A5: XXXXXXXX   A6: XXXXXXXX   A7: XXXXXXXX
31   PC: XXXXXXXX   SR: XXXX
32
33   OldMask: XXXXXXXX  Vector: XXXX
34
35   FP0: XXXXXXXXXXXXXXXXXXXXXXXX   FP1: XXXXXXXXXXXXXXXXXXXXXXXX
36   FP2: XXXXXXXXXXXXXXXXXXXXXXXX   FP3: XXXXXXXXXXXXXXXXXXXXXXXX
37   FP4: XXXXXXXXXXXXXXXXXXXXXXXX   FP5: XXXXXXXXXXXXXXXXXXXXXXXX
38   FP6: XXXXXXXXXXXXXXXXXXXXXXXX   FP7: XXXXXXXXXXXXXXXXXXXXXXXX
39   FPCR: XXXXXXXX   FPSR: XXXXXXXX   FPIAR: XXXXXXXX
40
41 */
42
43 #ifndef __mcoldfire__
44 /* Linux saves only the call-clobbered registers in the sigcontext.  We
45    need to use a trampoline that saves the rest so that the C code can
46    access them.  We use the sc_fpstate field, since the handler is not
47    supposed to return anyway, thus it doesn't matter that it's clobbered.  */
48
49 /* static */ void catch_segfault (int, int, struct sigcontext *);
50
51 /* Dummy function so that we can use asm with arguments.  */
52 static void __attribute_used__
53 __dummy__ (void)
54 {
55   asm ("\n\
56 catch_segfault:\n\
57         move.l 12(%%sp),%%a0\n\
58         lea %c0(%%a0),%%a0\n\
59         /* Clear the first 4 bytes to make it a null fp state, just\n\
60            in case the handler does return.  */\n\
61         clr.l (%%a0)+\n\
62         movem.l %%d2-%%d7/%%a2-%%a6,(%%a0)\n\
63         fmovem.x %%fp2-%%fp7,11*4(%%a0)\n\
64         jra real_catch_segfault"
65        : : "n" (offsetof (struct sigcontext, sc_fpstate)));
66 }
67 #define catch_segfault(a,b) \
68   __attribute_used__ real_catch_segfault(a,b)
69 #endif
70
71 static void
72 hexvalue (unsigned long int value, char *buf, size_t len)
73 {
74   char *cp = _itoa_word (value, buf + len, 16, 0);
75   while (cp > buf)
76     *--cp = '0';
77 }
78
79 static void
80 register_dump (int fd, struct sigcontext *ctx)
81 {
82   char regs[20][8];
83   char fpregs[11][24];
84   struct iovec iov[63], *next_iov = iov;
85   unsigned long *p = (unsigned long *) ctx->sc_fpstate + 1;
86   unsigned long *pfp = (unsigned long *) ctx->sc_fpregs;
87   int i, j, fpreg_size;
88
89 #define ADD_STRING(str) \
90   next_iov->iov_base = (char *) (str); \
91   next_iov->iov_len = strlen (str); \
92   ++next_iov
93 #define ADD_MEM(str, len) \
94   next_iov->iov_base = (str); \
95   next_iov->iov_len = (len); \
96   ++next_iov
97
98 #ifdef __mcoldfire__
99   fpreg_size = 16;
100 #else
101   fpreg_size = 24;
102 #endif
103
104   /* Generate strings of register contents.  */
105   hexvalue (ctx->sc_d0, regs[0], 8);
106   hexvalue (ctx->sc_d1, regs[1], 8);
107 #ifdef __mcoldfire__
108   hexvalue (ctx->sc_d2, regs[2], 8);
109   hexvalue (ctx->sc_d3, regs[3], 8);
110   hexvalue (ctx->sc_d4, regs[4], 8);
111   hexvalue (ctx->sc_d5, regs[5], 8);
112   hexvalue (ctx->sc_d6, regs[6], 8);
113   hexvalue (ctx->sc_d7, regs[7], 8);
114 #else
115   hexvalue (*p++, regs[2], 8);
116   hexvalue (*p++, regs[3], 8);
117   hexvalue (*p++, regs[4], 8);
118   hexvalue (*p++, regs[5], 8);
119   hexvalue (*p++, regs[6], 8);
120   hexvalue (*p++, regs[7], 8);
121 #endif
122   hexvalue (ctx->sc_a0, regs[8], 8);
123   hexvalue (ctx->sc_a1, regs[9], 8);
124 #ifdef __mcoldfire__
125   hexvalue (ctx->sc_a2, regs[10], 8);
126   hexvalue (ctx->sc_a3, regs[11], 8);
127   hexvalue (ctx->sc_a4, regs[12], 8);
128   hexvalue (ctx->sc_a5, regs[13], 8);
129   hexvalue (ctx->sc_a6, regs[14], 8);
130 #else
131   hexvalue (*p++, regs[10], 8);
132   hexvalue (*p++, regs[11], 8);
133   hexvalue (*p++, regs[12], 8);
134   hexvalue (*p++, regs[13], 8);
135   hexvalue (*p++, regs[14], 8);
136 #endif
137   hexvalue (ctx->sc_usp, regs[15], 8);
138   hexvalue (ctx->sc_pc, regs[16], 8);
139   hexvalue (ctx->sc_sr, regs[17], 4);
140   hexvalue (ctx->sc_mask, regs[18], 8);
141   hexvalue (ctx->sc_formatvec & 0xfff, regs[19], 4);
142   for (i = 0; i < 2; i++)
143     for (j = 0; j < fpreg_size; j += 8)
144       hexvalue (*pfp++, fpregs[i] + j, 8);
145 #ifdef __mcoldfire__
146   p = pfp;
147 #endif
148   for (i = 2; i < 8; i++)
149     for (j = 0; j < fpreg_size; j += 8)
150       hexvalue (*p++, fpregs[i] + j, 8);
151   hexvalue (ctx->sc_fpcntl[0], fpregs[8], 8);
152   hexvalue (ctx->sc_fpcntl[1], fpregs[9], 8);
153   hexvalue (ctx->sc_fpcntl[2], fpregs[10], 8);
154
155   /* Generate the output.  */
156   ADD_STRING ("Register dump:\n\n  D0: ");
157   ADD_MEM (regs[0], 8);
158   ADD_STRING ("  D1: ");
159   ADD_MEM (regs[1], 8);
160   ADD_STRING ("  D2: ");
161   ADD_MEM (regs[2], 8);
162   ADD_STRING ("  D3: ");
163   ADD_MEM (regs[3], 8);
164   ADD_STRING ("\n  D4: ");
165   ADD_MEM (regs[4], 8);
166   ADD_STRING ("  D5: ");
167   ADD_MEM (regs[5], 8);
168   ADD_STRING ("  D6: ");
169   ADD_MEM (regs[6], 8);
170   ADD_STRING ("  D7: ");
171   ADD_MEM (regs[7], 8);
172   ADD_STRING ("\n  A0: ");
173   ADD_MEM (regs[8], 8);
174   ADD_STRING ("  A1: ");
175   ADD_MEM (regs[9], 8);
176   ADD_STRING ("  A2: ");
177   ADD_MEM (regs[10], 8);
178   ADD_STRING ("  A3: ");
179   ADD_MEM (regs[11], 8);
180   ADD_STRING ("\n  A4: ");
181   ADD_MEM (regs[12], 8);
182   ADD_STRING ("  A5: ");
183   ADD_MEM (regs[13], 8);
184   ADD_STRING ("  A6: ");
185   ADD_MEM (regs[14], 8);
186   ADD_STRING ("  A7: ");
187   ADD_MEM (regs[15], 8);
188   ADD_STRING ("\n  PC: ");
189   ADD_MEM (regs[16], 8);
190   ADD_STRING ("  SR: ");
191   ADD_MEM (regs[17], 4);
192
193   ADD_STRING ("\n\n  OldMask: ");
194   ADD_MEM (regs[18], 8);
195   ADD_STRING ("  Vector: ");
196   ADD_MEM (regs[19], 4);
197
198   ADD_STRING ("\n\n  FP0: ");
199   ADD_MEM (fpregs[0], fpreg_size);
200   ADD_STRING ("  FP1: ");
201   ADD_MEM (fpregs[1], fpreg_size);
202   ADD_STRING ("\n  FP2: ");
203   ADD_MEM (fpregs[2], fpreg_size);
204   ADD_STRING ("  FP3: ");
205   ADD_MEM (fpregs[3], fpreg_size);
206   ADD_STRING ("\n  FP4: ");
207   ADD_MEM (fpregs[4], fpreg_size);
208   ADD_STRING ("  FP5: ");
209   ADD_MEM (fpregs[5], fpreg_size);
210   ADD_STRING ("\n  FP6: ");
211   ADD_MEM (fpregs[6], fpreg_size);
212   ADD_STRING ("  FP7: ");
213   ADD_MEM (fpregs[7], fpreg_size);
214   ADD_STRING ("\n  FPCR: ");
215   ADD_MEM (fpregs[8], 8);
216   ADD_STRING ("  FPSR: ");
217   ADD_MEM (fpregs[9], 8);
218   ADD_STRING ("  FPIAR: ");
219   ADD_MEM (fpregs[10], 8);
220   ADD_STRING ("\n");
221
222   /* Write the stuff out.  */
223   writev (fd, iov, next_iov - iov);
224 }
225
226 #define REGISTER_DUMP register_dump (fd, ctx)