1 /* Dump registers.
2    Copyright (C) 1999-2021 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <sys/uio.h>
20 #include <_itoa.h>
21 
22 /* We will print the register dump in this format:
23 
24  PSR: XXXXXXXX PC: XXXXXXXX NPC: XXXXXXXX   Y: XXXXXXXX
25  g0: 00000000  g1: XXXXXXXX  g2: XXXXXXXX  g3: XXXXXXXX
26  g4: XXXXXXXX  g5: XXXXXXXX  g6: XXXXXXXX  g7: XXXXXXXX
27  o0: XXXXXXXX  o1: XXXXXXXX  o2: XXXXXXXX  o3: XXXXXXXX
28  o4: XXXXXXXX  o5: XXXXXXXX  sp: XXXXXXXX  o7: XXXXXXXX
29  l0: XXXXXXXX  l1: XXXXXXXX  l2: XXXXXXXX  l3: XXXXXXXX
30  l4: XXXXXXXX  l5: XXXXXXXX  l6: XXXXXXXX  l7: XXXXXXXX
31  i0: XXXXXXXX  i1: XXXXXXXX  i2: XXXXXXXX  i3: XXXXXXXX
32  i4: XXXXXXXX  i5: XXXXXXXX  fp: XXXXXXXX  i7: XXXXXXXX
33 
34  followed on sun4, sun4c, sun4d, sun4m by:
35 
36  Old mask: XXXXXXXX FSR: XXXXXXXX FPQ: XXXXXXXX
37   f0: XXXXXXXXXXXXXXXX   f2: XXXXXXXXXXXXXXXX   f4: XXXXXXXXXXXXXXXX
38   f6: XXXXXXXXXXXXXXXX   f8: XXXXXXXXXXXXXXXX  f10: XXXXXXXXXXXXXXXX
39  f12: XXXXXXXXXXXXXXXX  f14: XXXXXXXXXXXXXXXX  f16: XXXXXXXXXXXXXXXX
40  f18: XXXXXXXXXXXXXXXX  f20: XXXXXXXXXXXXXXXX  f22: XXXXXXXXXXXXXXXX
41  f24: XXXXXXXXXXXXXXXX  f26: XXXXXXXXXXXXXXXX  f28: XXXXXXXXXXXXXXXX
42  f30: XXXXXXXXXXXXXXXX
43 
44  and on sun4u by:
45 
46  Old mask: XXXXXXXX XFSR: XXXXXXXXXXXXXXXX GSR: XX FPRS: X
47   f0: XXXXXXXXXXXXXXXX   f2: XXXXXXXXXXXXXXXX   f4: XXXXXXXXXXXXXXXX
48   f6: XXXXXXXXXXXXXXXX   f8: XXXXXXXXXXXXXXXX  f10: XXXXXXXXXXXXXXXX
49  f12: XXXXXXXXXXXXXXXX  f14: XXXXXXXXXXXXXXXX  f16: XXXXXXXXXXXXXXXX
50  f18: XXXXXXXXXXXXXXXX  f20: XXXXXXXXXXXXXXXX  f22: XXXXXXXXXXXXXXXX
51  f24: XXXXXXXXXXXXXXXX  f26: XXXXXXXXXXXXXXXX  f28: XXXXXXXXXXXXXXXX
52  f30: XXXXXXXXXXXXXXXX  f32: XXXXXXXXXXXXXXXX  f34: XXXXXXXXXXXXXXXX
53  f36: XXXXXXXXXXXXXXXX  f38: XXXXXXXXXXXXXXXX  f40: XXXXXXXXXXXXXXXX
54  f42: XXXXXXXXXXXXXXXX  f44: XXXXXXXXXXXXXXXX  f46: XXXXXXXXXXXXXXXX
55  f48: XXXXXXXXXXXXXXXX  f50: XXXXXXXXXXXXXXXX  f52: XXXXXXXXXXXXXXXX
56  f54: XXXXXXXXXXXXXXXX  f56: XXXXXXXXXXXXXXXX  f58: XXXXXXXXXXXXXXXX
57  f60: XXXXXXXXXXXXXXXX  f62: XXXXXXXXXXXXXXXX
58 
59  */
60 
61 static void
hexvalue(unsigned long int value,char * buf,size_t len)62 hexvalue (unsigned long int value, char *buf, size_t len)
63 {
64   char *cp = _itoa_word (value, buf + len, 16, 0);
65   while (cp > buf)
66     *--cp = '0';
67 }
68 
69 struct __siginfo_sparc32_fpu
70 {
71   unsigned int si_float_regs[32];
72   unsigned int si_fsr;
73   unsigned int si_fpq;
74 };
75 struct __siginfo_sparc64_fpu
76 {
77   unsigned int si_float_regs[64];
78   unsigned int si_xfsr;
79   unsigned int si_fsr;
80   unsigned int _pad1;
81   unsigned int si_gsr;
82   unsigned int _pad2;
83   unsigned int si_fprs;
84 };
85 
86 /* Unlike other architectures, sparc32 passes pt_regs32 REGS pointer as
87    the third argument to a sa_sigaction handler with SA_SIGINFO enabled.  */
88 static void
register_dump(int fd,void * ctx)89 register_dump (int fd, void *ctx)
90 {
91   char regs[36][8];
92   char fregs[68][8];
93   struct iovec iov[150];
94   size_t nr = 0;
95   int i;
96   struct pt_regs32 *ptregs = (struct pt_regs32 *) ctx;
97   struct compat_sigset_t
98   {
99     unsigned int sig[2];
100   };
101   struct compat_sigset_t *mask = (struct compat_sigset_t *)(ptregs + 1);
102   unsigned int *r = (unsigned int *) ptregs->u_regs[14];
103 
104 #define ADD_STRING(str) \
105   iov[nr].iov_base = (char *) str;					      \
106   iov[nr].iov_len = strlen (str);					      \
107   ++nr
108 #define ADD_MEM(str, len) \
109   iov[nr].iov_base = str;						      \
110   iov[nr].iov_len = len;						      \
111   ++nr
112 
113   /* Generate strings of register contents.  */
114   hexvalue (ptregs->psr, regs[0], 8);
115   hexvalue (ptregs->pc, regs[1], 8);
116   hexvalue (ptregs->npc, regs[2], 8);
117   hexvalue (ptregs->y, regs[3], 8);
118   for (i = 1; i <= 15; i++)
119     hexvalue (ptregs->u_regs[i], regs[3+i], 8);
120   for (i = 0; i <= 15; i++)
121     hexvalue (r[i], regs[19+i], 8);
122 
123   hexvalue (mask->sig[0], regs[35], 8);
124 
125   /* Generate the output.  */
126   ADD_STRING ("Register dump:\n\n PSR: ");
127   ADD_MEM (regs[0], 8);
128   ADD_STRING (" PC: ");
129   ADD_MEM (regs[1], 8);
130   ADD_STRING (" NPC: ");
131   ADD_MEM (regs[2], 8);
132   ADD_STRING ("   Y: ");
133   ADD_MEM (regs[3], 8);
134   ADD_STRING ("\n g0: 00000000 g1: ");
135   ADD_MEM (regs[4], 8);
136   ADD_STRING ("  g2: ");
137   ADD_MEM (regs[5], 8);
138   ADD_STRING ("  g3: ");
139   ADD_MEM (regs[6], 8);
140   ADD_STRING ("\n g4: ");
141   ADD_MEM (regs[7], 8);
142   ADD_STRING ("  g5: ");
143   ADD_MEM (regs[8], 8);
144   ADD_STRING ("  g6: ");
145   ADD_MEM (regs[9], 8);
146   ADD_STRING ("  g7: ");
147   ADD_MEM (regs[10], 8);
148   ADD_STRING ("\n o0: ");
149   ADD_MEM (regs[11], 8);
150   ADD_STRING ("  o1: ");
151   ADD_MEM (regs[12], 8);
152   ADD_STRING ("  o2: ");
153   ADD_MEM (regs[13], 8);
154   ADD_STRING ("  o3: ");
155   ADD_MEM (regs[14], 8);
156   ADD_STRING ("\n o4: ");
157   ADD_MEM (regs[15], 8);
158   ADD_STRING ("  o5: ");
159   ADD_MEM (regs[16], 8);
160   ADD_STRING ("  sp: ");
161   ADD_MEM (regs[17], 8);
162   ADD_STRING ("  o7: ");
163   ADD_MEM (regs[18], 8);
164   ADD_STRING ("\n l0: ");
165   ADD_MEM (regs[19], 8);
166   ADD_STRING ("  l1: ");
167   ADD_MEM (regs[20], 8);
168   ADD_STRING ("  l2: ");
169   ADD_MEM (regs[21], 8);
170   ADD_STRING ("  l3: ");
171   ADD_MEM (regs[22], 8);
172   ADD_STRING ("\n l4: ");
173   ADD_MEM (regs[23], 8);
174   ADD_STRING ("  l5: ");
175   ADD_MEM (regs[24], 8);
176   ADD_STRING ("  l6: ");
177   ADD_MEM (regs[25], 8);
178   ADD_STRING ("  l7: ");
179   ADD_MEM (regs[26], 8);
180   ADD_STRING ("\n i0: ");
181   ADD_MEM (regs[27], 8);
182   ADD_STRING ("  i1: ");
183   ADD_MEM (regs[28], 8);
184   ADD_STRING ("  i2: ");
185   ADD_MEM (regs[29], 8);
186   ADD_STRING ("  i3: ");
187   ADD_MEM (regs[30], 8);
188   ADD_STRING ("\n i4: ");
189   ADD_MEM (regs[31], 8);
190   ADD_STRING ("  i5: ");
191   ADD_MEM (regs[32], 8);
192   ADD_STRING ("  fp: ");
193   ADD_MEM (regs[33], 8);
194   ADD_STRING ("  i7: ");
195   ADD_MEM (regs[34], 8);
196   ADD_STRING ("\n\n Old mask: ");
197   ADD_MEM (regs[35], 8);
198 
199   if ((ptregs->psr & 0xff000000) == 0xff000000)
200     {
201       struct __siginfo_sparc64_fpu *f = *(struct __siginfo_sparc64_fpu **)
202 	(mask + 1);
203 
204       if (f != NULL)
205 	{
206 	  for (i = 0; i < 64; i++)
207 	    hexvalue (f->si_float_regs[i], fregs[i], 8);
208 	  hexvalue (f->si_xfsr, fregs[64], 8);
209 	  hexvalue (f->si_fsr, fregs[65], 8);
210 	  hexvalue (f->si_gsr, fregs[66], 2);
211 	  hexvalue (f->si_fprs, fregs[67], 1);
212 	  ADD_STRING (" XFSR: ");
213 	  ADD_MEM (fregs[64], 8);
214 	  ADD_MEM (fregs[65], 8);
215 	  ADD_STRING (" GSR: ");
216 	  ADD_MEM (fregs[66], 2);
217 	  ADD_STRING (" FPRS: ");
218 	  ADD_MEM (fregs[67], 1);
219 	  ADD_STRING ("\n  f0: ");
220 	  ADD_MEM (fregs[0], 16);
221 	  ADD_STRING ("   f2: ");
222 	  ADD_MEM (fregs[2], 16);
223 	  ADD_STRING ("   f4: ");
224 	  ADD_MEM (fregs[4], 16);
225 	  ADD_STRING ("\n  f6: ");
226 	  ADD_MEM (fregs[6], 16);
227 	  ADD_STRING ("   f8: ");
228 	  ADD_MEM (fregs[8], 16);
229 	  ADD_STRING ("  f10: ");
230 	  ADD_MEM (fregs[10], 16);
231 	  ADD_STRING ("\n f12: ");
232 	  ADD_MEM (fregs[12], 16);
233 	  ADD_STRING ("  f14: ");
234 	  ADD_MEM (fregs[14], 16);
235 	  ADD_STRING ("  f16: ");
236 	  ADD_MEM (fregs[16], 16);
237 	  ADD_STRING ("\n f18: ");
238 	  ADD_MEM (fregs[18], 16);
239 	  ADD_STRING ("  f20: ");
240 	  ADD_MEM (fregs[20], 16);
241 	  ADD_STRING ("  f22: ");
242 	  ADD_MEM (fregs[22], 16);
243 	  ADD_STRING ("\n f24: ");
244 	  ADD_MEM (fregs[24], 16);
245 	  ADD_STRING ("  f26: ");
246 	  ADD_MEM (fregs[26], 16);
247 	  ADD_STRING ("  f28: ");
248 	  ADD_MEM (fregs[28], 16);
249 	  ADD_STRING ("\n f30: ");
250 	  ADD_MEM (fregs[30], 16);
251 	  ADD_STRING ("  f32: ");
252 	  ADD_MEM (fregs[32], 16);
253 	  ADD_STRING ("  f34: ");
254 	  ADD_MEM (fregs[34], 16);
255 	  ADD_STRING ("\n f36: ");
256 	  ADD_MEM (fregs[36], 16);
257 	  ADD_STRING ("  f38: ");
258 	  ADD_MEM (fregs[38], 16);
259 	  ADD_STRING ("  f40: ");
260 	  ADD_MEM (fregs[40], 16);
261 	  ADD_STRING ("\n f42: ");
262 	  ADD_MEM (fregs[42], 16);
263 	  ADD_STRING ("  f44: ");
264 	  ADD_MEM (fregs[44], 16);
265 	  ADD_STRING ("  f46: ");
266 	  ADD_MEM (fregs[46], 16);
267 	  ADD_STRING ("\n f48: ");
268 	  ADD_MEM (fregs[48], 16);
269 	  ADD_STRING ("  f50: ");
270 	  ADD_MEM (fregs[50], 16);
271 	  ADD_STRING ("  f52: ");
272 	  ADD_MEM (fregs[52], 16);
273 	  ADD_STRING ("\n f54: ");
274 	  ADD_MEM (fregs[54], 16);
275 	  ADD_STRING ("  f56: ");
276 	  ADD_MEM (fregs[56], 16);
277 	  ADD_STRING ("  f58: ");
278 	  ADD_MEM (fregs[58], 16);
279 	  ADD_STRING ("\n f60: ");
280 	  ADD_MEM (fregs[60], 16);
281 	  ADD_STRING ("  f62: ");
282 	  ADD_MEM (fregs[62], 16);
283 	}
284     }
285   else
286     {
287       struct __siginfo_sparc32_fpu *f = *(struct __siginfo_sparc32_fpu **)
288 	(mask + 1);
289 
290       if (f != NULL)
291 	{
292 	  for (i = 0; i < 32; i++)
293 	    hexvalue (f->si_float_regs[i], fregs[i], 8);
294 	  hexvalue (f->si_fsr, fregs[64], 8);
295 	  hexvalue (f->si_fpq, fregs[65], 8);
296 	  ADD_STRING (" FSR: ");
297 	  ADD_MEM (fregs[64], 8);
298 	  ADD_STRING (" FPQ: ");
299 	  ADD_MEM (fregs[65], 8);
300 	  ADD_STRING ("\n  f0: ");
301 	  ADD_MEM (fregs[0], 16);
302 	  ADD_STRING ("  f2: ");
303 	  ADD_MEM (fregs[2], 16);
304 	  ADD_STRING ("  f4: ");
305 	  ADD_MEM (fregs[4], 16);
306 	  ADD_STRING ("\n  f6: ");
307 	  ADD_MEM (fregs[6], 16);
308 	  ADD_STRING ("   f8: ");
309 	  ADD_MEM (fregs[8], 16);
310 	  ADD_STRING ("  f10: ");
311 	  ADD_MEM (fregs[10], 16);
312 	  ADD_STRING ("\n  f12: ");
313 	  ADD_MEM (fregs[12], 16);
314 	  ADD_STRING ("  f14: ");
315 	  ADD_MEM (fregs[14], 16);
316 	  ADD_STRING ("  f16: ");
317 	  ADD_MEM (fregs[16], 16);
318 	  ADD_STRING ("\n f18: ");
319 	  ADD_MEM (fregs[18], 16);
320 	  ADD_STRING ("  f20: ");
321 	  ADD_MEM (fregs[20], 16);
322 	  ADD_STRING ("  f22: ");
323 	  ADD_MEM (fregs[22], 16);
324 	  ADD_STRING ("\n f24: ");
325 	  ADD_MEM (fregs[24], 16);
326 	  ADD_STRING ("  f26: ");
327 	  ADD_MEM (fregs[26], 16);
328 	  ADD_STRING ("  f28: ");
329 	  ADD_MEM (fregs[28], 16);
330 	  ADD_STRING ("\n f30: ");
331 	  ADD_MEM (fregs[30], 16);
332 	}
333     }
334 
335   ADD_STRING ("\n");
336 
337   /* Write the stuff out.  */
338   writev (fd, iov, nr);
339 }
340 
341 
342 #define REGISTER_DUMP register_dump (fd, ctx)
343