de68ccbd0e497ae9de1681553e2ca36136da176f
[platform/upstream/glibc.git] / sysdeps / unix / sysv / linux / sparc / sparc64 / register-dump.h
1 /* Dump registers.
2    Copyright (C) 1999-2022 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  TSTATE: XXXXXXXXXXXXXXXX TPC: XXXXXXXXXXXXXXXX TNPC: XXXXXXXXXXXXXXXX
25  Y: XXXXXXXX
26  g0: 0000000000000000  g1: XXXXXXXXXXXXXXXX  g2: XXXXXXXXXXXXXXXX
27  g3: XXXXXXXXXXXXXXXX  g4: XXXXXXXXXXXXXXXX  g5: XXXXXXXXXXXXXXXX
28  g6: XXXXXXXXXXXXXXXX  g7: XXXXXXXXXXXXXXXX
29  o0: XXXXXXXXXXXXXXXX  o1: XXXXXXXXXXXXXXXX  o2: XXXXXXXXXXXXXXXX
30  o3: XXXXXXXXXXXXXXXX  o4: XXXXXXXXXXXXXXXX  o5: XXXXXXXXXXXXXXXX
31  sp: XXXXXXXXXXXXXXXX  o7: XXXXXXXXXXXXXXXX
32  l0: XXXXXXXXXXXXXXXX  l1: XXXXXXXXXXXXXXXX  l2: XXXXXXXXXXXXXXXX
33  l3: XXXXXXXXXXXXXXXX  l4: XXXXXXXXXXXXXXXX  l5: XXXXXXXXXXXXXXXX
34  l6: XXXXXXXXXXXXXXXX  l7: XXXXXXXXXXXXXXXX
35  i0: XXXXXXXXXXXXXXXX  i1: XXXXXXXXXXXXXXXX  i2: XXXXXXXXXXXXXXXX
36  i3: XXXXXXXXXXXXXXXX  i4: XXXXXXXXXXXXXXXX  i5: XXXXXXXXXXXXXXXX
37  fp: XXXXXXXXXXXXXXXX  i7: XXXXXXXXXXXXXXXX
38
39  Mask: XXXXXXXXXXXXXXXX XFSR: XXXXXXXXXXXXXXXX GSR: XX FPRS: X
40   f0: XXXXXXXXXXXXXXXX   f2: XXXXXXXXXXXXXXXX   f4: XXXXXXXXXXXXXXXX
41   f6: XXXXXXXXXXXXXXXX   f8: XXXXXXXXXXXXXXXX  f10: XXXXXXXXXXXXXXXX
42  f12: XXXXXXXXXXXXXXXX  f14: XXXXXXXXXXXXXXXX  f16: XXXXXXXXXXXXXXXX
43  f18: XXXXXXXXXXXXXXXX  f20: XXXXXXXXXXXXXXXX  f22: XXXXXXXXXXXXXXXX
44  f24: XXXXXXXXXXXXXXXX  f26: XXXXXXXXXXXXXXXX  f28: XXXXXXXXXXXXXXXX
45  f30: XXXXXXXXXXXXXXXX  f32: XXXXXXXXXXXXXXXX  f34: XXXXXXXXXXXXXXXX
46  f36: XXXXXXXXXXXXXXXX  f38: XXXXXXXXXXXXXXXX  f40: XXXXXXXXXXXXXXXX
47  f42: XXXXXXXXXXXXXXXX  f44: XXXXXXXXXXXXXXXX  f46: XXXXXXXXXXXXXXXX
48  f48: XXXXXXXXXXXXXXXX  f50: XXXXXXXXXXXXXXXX  f52: XXXXXXXXXXXXXXXX
49  f54: XXXXXXXXXXXXXXXX  f56: XXXXXXXXXXXXXXXX  f58: XXXXXXXXXXXXXXXX
50  f60: XXXXXXXXXXXXXXXX  f62: XXXXXXXXXXXXXXXX
51
52  */
53
54 static void
55 hexvalue (unsigned long int value, char *buf, size_t len)
56 {
57   char *cp = _itoa_word (value, buf + len, 16, 0);
58   while (cp > buf)
59     *--cp = '0';
60 }
61
62 /* The sparc64 kernel signal frame for SA_SIGINFO is defined as:
63
64    struct rt_signal_frame
65      {
66        struct sparc_stackf ss;
67        siginfo_t info;
68        struct pt_regs regs;          <- void *ctx
69        __siginfo_fpu_t *fpu_save;
70        stack_t stack;
71        sigset_t mask;
72        __siginfo_rwin_t *rwin_save;
73      };
74
75   Unlike other architectures, sparc32 passes pt_regs32 REGS pointers as
76   the third argument to a sa_sigaction handler with SA_SIGINFO enabled.  */
77
78 static void
79 register_dump (int fd, void *ctx)
80 {
81   char regs[36][16];
82   char fregs[68][8];
83   struct iovec iov[150];
84   size_t nr = 0;
85   int i;
86   struct pt_regs *ptregs = (struct pt_regs*) ((siginfo_t *)ctx + 1);
87   unsigned long *r = (unsigned long *) (ptregs->u_regs[14] + STACK_BIAS);
88   __siginfo_fpu_t *f = (__siginfo_fpu_t *)(ptregs + 1);
89   struct kernel_sigset_t {
90     unsigned long sig[1];
91   } *mask = (struct kernel_sigset_t *)((stack_t *)(f + 1) + 1);
92
93 #define ADD_STRING(str) \
94   iov[nr].iov_base = (char *) str;                                            \
95   iov[nr].iov_len = strlen (str);                                             \
96   ++nr
97 #define ADD_MEM(str, len) \
98   iov[nr].iov_base = str;                                                     \
99   iov[nr].iov_len = len;                                                      \
100   ++nr
101
102   /* Generate strings of register contents.  */
103   hexvalue (ptregs->tstate, regs[0], 16);
104   hexvalue (ptregs->tpc, regs[1], 16);
105   hexvalue (ptregs->tnpc, regs[2], 16);
106   hexvalue (ptregs->y, regs[3], 8);
107   for (i = 1; i <= 15; i++)
108     hexvalue (ptregs->u_regs[i], regs[3+i], 16);
109   for (i = 0; i <= 15; i++)
110     hexvalue (r[i], regs[19+i], 16);
111   hexvalue (mask->sig[0], regs[35], 16);
112
113   /* Generate the output.  */
114   ADD_STRING ("Register dump:\n\n TSTATE: ");
115   ADD_MEM (regs[0], 16);
116   ADD_STRING (" TPC: ");
117   ADD_MEM (regs[1], 16);
118   ADD_STRING (" TNPC: ");
119   ADD_MEM (regs[2], 16);
120   ADD_STRING ("\n Y: ");
121   ADD_MEM (regs[3], 8);
122   ADD_STRING ("\n  g0: 0000000000000000   g1: ");
123   ADD_MEM (regs[4], 16);
124   ADD_STRING ("  g2: ");
125   ADD_MEM (regs[5], 16);
126   ADD_STRING ("\n g3: ");
127   ADD_MEM (regs[6], 16);
128   ADD_STRING ("  g4: ");
129   ADD_MEM (regs[7], 16);
130   ADD_STRING ("  g5: ");
131   ADD_MEM (regs[8], 16);
132   ADD_STRING ("\n g6: ");
133   ADD_MEM (regs[9], 16);
134   ADD_STRING ("  g7: ");
135   ADD_MEM (regs[10], 16);
136   ADD_STRING ("\n o0: ");
137   ADD_MEM (regs[11], 16);
138   ADD_STRING ("  o1: ");
139   ADD_MEM (regs[12], 16);
140   ADD_STRING ("  o2: ");
141   ADD_MEM (regs[13], 16);
142   ADD_STRING ("\n o3: ");
143   ADD_MEM (regs[14], 16);
144   ADD_STRING ("  o4: ");
145   ADD_MEM (regs[15], 16);
146   ADD_STRING ("  o5: ");
147   ADD_MEM (regs[16], 16);
148   ADD_STRING ("\n sp: ");
149   ADD_MEM (regs[17], 16);
150   ADD_STRING ("  o7: ");
151   ADD_MEM (regs[18], 16);
152   ADD_STRING ("\n l0: ");
153   ADD_MEM (regs[19], 16);
154   ADD_STRING ("  l1: ");
155   ADD_MEM (regs[20], 16);
156   ADD_STRING ("  l2: ");
157   ADD_MEM (regs[21], 16);
158   ADD_STRING ("\n l3: ");
159   ADD_MEM (regs[22], 16);
160   ADD_STRING ("  l4: ");
161   ADD_MEM (regs[23], 16);
162   ADD_STRING ("  l5: ");
163   ADD_MEM (regs[24], 16);
164   ADD_STRING ("\n l6: ");
165   ADD_MEM (regs[25], 16);
166   ADD_STRING ("  l7: ");
167   ADD_MEM (regs[26], 16);
168   ADD_STRING ("\n i0: ");
169   ADD_MEM (regs[27], 16);
170   ADD_STRING ("  i1: ");
171   ADD_MEM (regs[28], 16);
172   ADD_STRING ("  i2: ");
173   ADD_MEM (regs[29], 16);
174   ADD_STRING ("\n i3: ");
175   ADD_MEM (regs[30], 16);
176   ADD_STRING ("  i4: ");
177   ADD_MEM (regs[31], 16);
178   ADD_STRING ("  i5: ");
179   ADD_MEM (regs[32], 16);
180   ADD_STRING ("\n fp: ");
181   ADD_MEM (regs[33], 16);
182   ADD_STRING ("  i7: ");
183   ADD_MEM (regs[34], 16);
184   ADD_STRING ("\n\n Mask: ");
185   ADD_MEM (regs[35], 16);
186
187   if (f != NULL)
188     {
189       for (i = 0; i < 64; i++)
190         hexvalue (f->si_float_regs[i], fregs[i], 8);
191       hexvalue (f->si_fsr, fregs[64], 16);
192       hexvalue (f->si_gsr, fregs[66], 2);
193       hexvalue (f->si_fprs, fregs[67], 1);
194       ADD_STRING (" XFSR: ");
195       ADD_MEM (fregs[64], 16);
196       ADD_STRING (" GSR: ");
197       ADD_MEM (fregs[66], 2);
198       ADD_STRING (" FPRS: ");
199       ADD_MEM (fregs[67], 1);
200       ADD_STRING ("\n  f0: ");
201       ADD_MEM (fregs[0], 16);
202       ADD_STRING ("   f2: ");
203       ADD_MEM (fregs[2], 16);
204       ADD_STRING ("   f4: ");
205       ADD_MEM (fregs[4], 16);
206       ADD_STRING ("\n  f6: ");
207       ADD_MEM (fregs[6], 16);
208       ADD_STRING ("   f8: ");
209       ADD_MEM (fregs[8], 16);
210       ADD_STRING ("  f10: ");
211       ADD_MEM (fregs[10], 16);
212       ADD_STRING ("\n f12: ");
213       ADD_MEM (fregs[12], 16);
214       ADD_STRING ("  f14: ");
215       ADD_MEM (fregs[14], 16);
216       ADD_STRING ("  f16: ");
217       ADD_MEM (fregs[16], 16);
218       ADD_STRING ("\n f18: ");
219       ADD_MEM (fregs[18], 16);
220       ADD_STRING ("  f20: ");
221       ADD_MEM (fregs[20], 16);
222       ADD_STRING ("  f22: ");
223       ADD_MEM (fregs[22], 16);
224       ADD_STRING ("\n f24: ");
225       ADD_MEM (fregs[24], 16);
226       ADD_STRING ("  f26: ");
227       ADD_MEM (fregs[26], 16);
228       ADD_STRING ("  f28: ");
229       ADD_MEM (fregs[28], 16);
230       ADD_STRING ("\n f30: ");
231       ADD_MEM (fregs[30], 16);
232       ADD_STRING ("  f32: ");
233       ADD_MEM (fregs[32], 16);
234       ADD_STRING ("  f34: ");
235       ADD_MEM (fregs[34], 16);
236       ADD_STRING ("\n f36: ");
237       ADD_MEM (fregs[36], 16);
238       ADD_STRING ("  f38: ");
239       ADD_MEM (fregs[38], 16);
240       ADD_STRING ("  f40: ");
241       ADD_MEM (fregs[40], 16);
242       ADD_STRING ("\n f42: ");
243       ADD_MEM (fregs[42], 16);
244       ADD_STRING ("  f44: ");
245       ADD_MEM (fregs[44], 16);
246       ADD_STRING ("  f46: ");
247       ADD_MEM (fregs[46], 16);
248       ADD_STRING ("\n f48: ");
249       ADD_MEM (fregs[48], 16);
250       ADD_STRING ("  f50: ");
251       ADD_MEM (fregs[50], 16);
252       ADD_STRING ("  f52: ");
253       ADD_MEM (fregs[52], 16);
254       ADD_STRING ("\n f54: ");
255       ADD_MEM (fregs[54], 16);
256       ADD_STRING ("  f56: ");
257       ADD_MEM (fregs[56], 16);
258       ADD_STRING ("  f58: ");
259       ADD_MEM (fregs[58], 16);
260       ADD_STRING ("\n f60: ");
261       ADD_MEM (fregs[60], 16);
262       ADD_STRING ("  f62: ");
263       ADD_MEM (fregs[62], 16);
264     }
265
266   ADD_STRING ("\n");
267
268   /* Write the stuff out.  */
269   writev (fd, iov, nr);
270 }
271
272
273 #define REGISTER_DUMP register_dump (fd, ctx)