1 /* Dump registers.
2    Copyright (C) 2001-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  RAX: XXXXXXXXXXXXXXXX   RBX: XXXXXXXXXXXXXXXX  RCX: XXXXXXXXXXXXXXXX
25  RDX: XXXXXXXXXXXXXXXX   RSI: XXXXXXXXXXXXXXXX  RDI: XXXXXXXXXXXXXXXX
26  RBP: XXXXXXXXXXXXXXXX   R8 : XXXXXXXXXXXXXXXX  R9 : XXXXXXXXXXXXXXXX
27  R10: XXXXXXXXXXXXXXXX   R11: XXXXXXXXXXXXXXXX  R12: XXXXXXXXXXXXXXXX
28  R13: XXXXXXXXXXXXXXXX   R14: XXXXXXXXXXXXXXXX  R15: XXXXXXXXXXXXXXXX
29  RSP: XXXXXXXXXXXXXXXX
30 
31  RIP: XXXXXXXXXXXXXXXX   EFLAGS: XXXXXXXX
32 
33  CS:  XXXX   DS: XXXX   ES: XXXX   FS: XXXX   GS: XXXX
34 
35  Trap:  XXXXXXXX   Error: XXXXXXXX   OldMask: XXXXXXXX
36  RSP/SIGNAL: XXXXXXXXXXXXXXXX  CR2: XXXXXXXX
37 
38  FPUCW: XXXXXXXX   FPUSW: XXXXXXXX   TAG: XXXXXXXX
39  IPOFF: XXXXXXXX   CSSEL: XXXX   DATAOFF: XXXXXXXX   DATASEL: XXXX
40 
41  ST(0) XXXX XXXXXXXXXXXXXXXX   ST(1) XXXX XXXXXXXXXXXXXXXX
42  ST(2) XXXX XXXXXXXXXXXXXXXX   ST(3) XXXX XXXXXXXXXXXXXXXX
43  ST(4) XXXX XXXXXXXXXXXXXXXX   ST(5) XXXX XXXXXXXXXXXXXXXX
44  ST(6) XXXX XXXXXXXXXXXXXXXX   ST(7) XXXX XXXXXXXXXXXXXXXX
45 
46  mxcsr: XXXX
47  XMM0 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM1 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
48  XMM2 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM3 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
49  XMM4 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM5 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
50  XMM6 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM7 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
51  XMM8 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM9 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
52  XMM10: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM11: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
53  XMM12: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM13: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
54  XMM14: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM15: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
55 
56  */
57 
58 static void
hexvalue(unsigned long int value,char * buf,size_t len)59 hexvalue (unsigned long int value, char *buf, size_t len)
60 {
61   char *cp = _itoa_word (value, buf + len, 16, 0);
62   while (cp > buf)
63     *--cp = '0';
64 }
65 
66 static void
register_dump(int fd,ucontext_t * ctx)67 register_dump (int fd, ucontext_t *ctx)
68 {
69   char regs[25][16];
70   char fpregs[30][8];
71   char xmmregs[16][32];
72   struct iovec iov[147];
73   size_t nr = 0;
74   int i;
75 
76 #define ADD_STRING(str) \
77   iov[nr].iov_base = (char *) str;					      \
78   iov[nr].iov_len = strlen (str);					      \
79   ++nr
80 #define ADD_MEM(str, len) \
81   iov[nr].iov_base = str;						      \
82   iov[nr].iov_len = len;						      \
83   ++nr
84 
85   /* Generate strings of register contents.  */
86   hexvalue (ctx->uc_mcontext.gregs[REG_RAX], regs[0], 16);
87   hexvalue (ctx->uc_mcontext.gregs[REG_RBX], regs[1], 16);
88   hexvalue (ctx->uc_mcontext.gregs[REG_RCX], regs[2], 16);
89   hexvalue (ctx->uc_mcontext.gregs[REG_RDX], regs[3], 16);
90   hexvalue (ctx->uc_mcontext.gregs[REG_RSI], regs[4], 16);
91   hexvalue (ctx->uc_mcontext.gregs[REG_RDI], regs[5], 16);
92   hexvalue (ctx->uc_mcontext.gregs[REG_RBP], regs[6], 16);
93   hexvalue (ctx->uc_mcontext.gregs[REG_R8], regs[7], 16);
94   hexvalue (ctx->uc_mcontext.gregs[REG_R9], regs[8], 16);
95   hexvalue (ctx->uc_mcontext.gregs[REG_R10], regs[9], 16);
96   hexvalue (ctx->uc_mcontext.gregs[REG_R11], regs[10], 16);
97   hexvalue (ctx->uc_mcontext.gregs[REG_R12], regs[11], 16);
98   hexvalue (ctx->uc_mcontext.gregs[REG_R13], regs[12], 16);
99   hexvalue (ctx->uc_mcontext.gregs[REG_R14], regs[13], 16);
100   hexvalue (ctx->uc_mcontext.gregs[REG_R15], regs[14], 16);
101   hexvalue (ctx->uc_mcontext.gregs[REG_RSP], regs[15], 16);
102   hexvalue (ctx->uc_mcontext.gregs[REG_RIP], regs[16], 16);
103 
104   hexvalue (ctx->uc_mcontext.gregs[REG_EFL], regs[17], 8);
105   hexvalue (ctx->uc_mcontext.gregs[REG_CSGSFS] & 0xffff, regs[18], 4);
106   hexvalue ((ctx->uc_mcontext.gregs[REG_CSGSFS] >> 16) & 0xffff, regs[19], 4);
107   hexvalue ((ctx->uc_mcontext.gregs[REG_CSGSFS] >> 32) & 0xffff, regs[20], 4);
108   /* hexvalue (ctx->ss, regs[23], 4); */
109   hexvalue (ctx->uc_mcontext.gregs[REG_TRAPNO], regs[21], 8);
110   hexvalue (ctx->uc_mcontext.gregs[REG_ERR], regs[22], 8);
111   hexvalue (ctx->uc_mcontext.gregs[REG_OLDMASK], regs[23], 8);
112   hexvalue (ctx->uc_mcontext.gregs[REG_CR2], regs[24], 8);
113 
114   /* Generate the output.  */
115   ADD_STRING ("Register dump:\n\n RAX: ");
116   ADD_MEM (regs[0], 16);
117   ADD_STRING ("   RBX: ");
118   ADD_MEM (regs[1], 16);
119   ADD_STRING ("   RCX: ");
120   ADD_MEM (regs[2], 16);
121   ADD_STRING ("\n RDX: ");
122   ADD_MEM (regs[3], 16);
123   ADD_STRING ("   RSI: ");
124   ADD_MEM (regs[4], 16);
125   ADD_STRING ("   RDI: ");
126   ADD_MEM (regs[5], 16);
127   ADD_STRING ("\n RBP: ");
128   ADD_MEM (regs[6], 16);
129   ADD_STRING ("   R8 : ");
130   ADD_MEM (regs[7], 16);
131   ADD_STRING ("   R9 : ");
132   ADD_MEM (regs[8], 16);
133   ADD_STRING ("\n R10: ");
134   ADD_MEM (regs[9], 16);
135   ADD_STRING ("   R11: ");
136   ADD_MEM (regs[10], 16);
137   ADD_STRING ("   R12: ");
138   ADD_MEM (regs[11], 16);
139   ADD_STRING ("\n R13: ");
140   ADD_MEM (regs[12], 16);
141   ADD_STRING ("   R14: ");
142   ADD_MEM (regs[13], 16);
143   ADD_STRING ("   R15: ");
144   ADD_MEM (regs[14], 16);
145   ADD_STRING ("\n RSP: ");
146   ADD_MEM (regs[15], 16);
147   ADD_STRING ("\n\n RIP: ");
148   ADD_MEM (regs[16], 16);
149   ADD_STRING ("   EFLAGS: ");
150   ADD_MEM (regs[17], 8);
151   ADD_STRING ("\n\n CS: ");
152   ADD_MEM (regs[18], 4);
153   ADD_STRING ("   FS: ");
154   ADD_MEM (regs[19], 4);
155   ADD_STRING ("   GS: ");
156   ADD_MEM (regs[20], 4);
157   /*
158   ADD_STRING ("   SS: ");
159   ADD_MEM (regs[23], 4);
160   */
161   ADD_STRING ("\n\n Trap: ");
162   ADD_MEM (regs[21], 8);
163   ADD_STRING ("   Error: ");
164   ADD_MEM (regs[22], 8);
165   ADD_STRING ("   OldMask: ");
166   ADD_MEM (regs[23], 8);
167   ADD_STRING ("   CR2: ");
168   ADD_MEM (regs[24], 8);
169 
170   if (ctx->uc_mcontext.fpregs != NULL)
171     {
172 
173       /* Generate output for the FPU control/status registers.  */
174       hexvalue (ctx->uc_mcontext.fpregs->cwd, fpregs[0], 8);
175       hexvalue (ctx->uc_mcontext.fpregs->swd, fpregs[1], 8);
176       hexvalue (ctx->uc_mcontext.fpregs->ftw, fpregs[2], 8);
177       hexvalue (ctx->uc_mcontext.fpregs->rip, fpregs[3], 8);
178       hexvalue (ctx->uc_mcontext.fpregs->rdp, fpregs[4], 8);
179 
180       ADD_STRING ("\n\n FPUCW: ");
181       ADD_MEM (fpregs[0], 8);
182       ADD_STRING ("   FPUSW: ");
183       ADD_MEM (fpregs[1], 8);
184       ADD_STRING ("   TAG: ");
185       ADD_MEM (fpregs[2], 8);
186       ADD_STRING ("\n RIP: ");
187       ADD_MEM (fpregs[3], 8);
188       ADD_STRING ("   RDP: ");
189       ADD_MEM (fpregs[4], 8);
190 
191       /* Now the real FPU registers.  */
192       hexvalue (ctx->uc_mcontext.fpregs->_st[0].exponent, fpregs[5], 8);
193       hexvalue (ctx->uc_mcontext.fpregs->_st[0].significand[3] << 16
194 		| ctx->uc_mcontext.fpregs->_st[0].significand[2], fpregs[6],
195 		8);
196       hexvalue (ctx->uc_mcontext.fpregs->_st[0].significand[1] << 16
197 		| ctx->uc_mcontext.fpregs->_st[0].significand[0], fpregs[7],
198 		8);
199       hexvalue (ctx->uc_mcontext.fpregs->_st[1].exponent, fpregs[8], 8);
200       hexvalue (ctx->uc_mcontext.fpregs->_st[1].significand[3] << 16
201 		| ctx->uc_mcontext.fpregs->_st[1].significand[2], fpregs[9],
202 		8);
203       hexvalue (ctx->uc_mcontext.fpregs->_st[1].significand[1] << 16
204 		| ctx->uc_mcontext.fpregs->_st[1].significand[0], fpregs[10],
205 		8);
206       hexvalue (ctx->uc_mcontext.fpregs->_st[2].exponent, fpregs[11], 8);
207       hexvalue (ctx->uc_mcontext.fpregs->_st[2].significand[3] << 16
208 		| ctx->uc_mcontext.fpregs->_st[2].significand[2], fpregs[12],
209 		8);
210       hexvalue (ctx->uc_mcontext.fpregs->_st[2].significand[1] << 16
211 		| ctx->uc_mcontext.fpregs->_st[2].significand[0], fpregs[13],
212 		8);
213       hexvalue (ctx->uc_mcontext.fpregs->_st[3].exponent, fpregs[14], 8);
214       hexvalue (ctx->uc_mcontext.fpregs->_st[3].significand[3] << 16
215 		| ctx->uc_mcontext.fpregs->_st[3].significand[2], fpregs[15],
216 		8);
217       hexvalue (ctx->uc_mcontext.fpregs->_st[3].significand[1] << 16
218 		| ctx->uc_mcontext.fpregs->_st[3].significand[0], fpregs[16],
219 		8);
220       hexvalue (ctx->uc_mcontext.fpregs->_st[4].exponent, fpregs[17], 8);
221       hexvalue (ctx->uc_mcontext.fpregs->_st[4].significand[3] << 16
222 		| ctx->uc_mcontext.fpregs->_st[4].significand[2], fpregs[18],
223 		8);
224       hexvalue (ctx->uc_mcontext.fpregs->_st[4].significand[1] << 16
225 		| ctx->uc_mcontext.fpregs->_st[4].significand[0], fpregs[19],
226 		8);
227       hexvalue (ctx->uc_mcontext.fpregs->_st[5].exponent, fpregs[20], 8);
228       hexvalue (ctx->uc_mcontext.fpregs->_st[5].significand[3] << 16
229 		| ctx->uc_mcontext.fpregs->_st[5].significand[2], fpregs[21],
230 		8);
231       hexvalue (ctx->uc_mcontext.fpregs->_st[5].significand[1] << 16
232 		| ctx->uc_mcontext.fpregs->_st[5].significand[0], fpregs[22],
233 		8);
234       hexvalue (ctx->uc_mcontext.fpregs->_st[6].exponent, fpregs[23], 8);
235       hexvalue (ctx->uc_mcontext.fpregs->_st[6].significand[3] << 16
236 		| ctx->uc_mcontext.fpregs->_st[6].significand[2], fpregs[24],
237 		8);
238       hexvalue (ctx->uc_mcontext.fpregs->_st[6].significand[1] << 16
239 		| ctx->uc_mcontext.fpregs->_st[6].significand[0], fpregs[25],
240 		8);
241       hexvalue (ctx->uc_mcontext.fpregs->_st[7].exponent, fpregs[26], 8);
242       hexvalue (ctx->uc_mcontext.fpregs->_st[7].significand[3] << 16
243 		| ctx->uc_mcontext.fpregs->_st[7].significand[2], fpregs[27],
244 		8);
245       hexvalue (ctx->uc_mcontext.fpregs->_st[7].significand[1] << 16
246 		| ctx->uc_mcontext.fpregs->_st[7].significand[0], fpregs[28],
247 		8);
248 
249       hexvalue (ctx->uc_mcontext.fpregs->mxcsr, fpregs[29], 4);
250 
251       for (i = 0; i < 16; i++)
252 	hexvalue (ctx->uc_mcontext.fpregs->_xmm[i].element[3] << 24
253 		  | ctx->uc_mcontext.fpregs->_xmm[i].element[2] << 16
254 		  | ctx->uc_mcontext.fpregs->_xmm[i].element[1] << 8
255 		  | ctx->uc_mcontext.fpregs->_xmm[i].element[0], xmmregs[i],
256 		  32);
257 
258 
259       ADD_STRING ("\n\n ST(0) ");
260       ADD_MEM (fpregs[5], 4);
261       ADD_STRING (" ");
262       ADD_MEM (fpregs[6], 8);
263       ADD_MEM (fpregs[7], 8);
264       ADD_STRING ("   ST(1) ");
265       ADD_MEM (fpregs[8], 4);
266       ADD_STRING (" ");
267       ADD_MEM (fpregs[9], 8);
268       ADD_MEM (fpregs[10], 8);
269       ADD_STRING ("\n ST(2) ");
270       ADD_MEM (fpregs[11], 4);
271       ADD_STRING (" ");
272       ADD_MEM (fpregs[12], 8);
273       ADD_MEM (fpregs[13], 8);
274       ADD_STRING ("   ST(3) ");
275       ADD_MEM (fpregs[14], 4);
276       ADD_STRING (" ");
277       ADD_MEM (fpregs[15], 8);
278       ADD_MEM (fpregs[16], 8);
279       ADD_STRING ("\n ST(4) ");
280       ADD_MEM (fpregs[17], 4);
281       ADD_STRING (" ");
282       ADD_MEM (fpregs[18], 8);
283       ADD_MEM (fpregs[19], 8);
284       ADD_STRING ("   ST(5) ");
285       ADD_MEM (fpregs[20], 4);
286       ADD_STRING (" ");
287       ADD_MEM (fpregs[21], 8);
288       ADD_MEM (fpregs[22], 8);
289       ADD_STRING ("\n ST(6) ");
290       ADD_MEM (fpregs[23], 4);
291       ADD_STRING (" ");
292       ADD_MEM (fpregs[24], 8);
293       ADD_MEM (fpregs[25], 8);
294       ADD_STRING ("   ST(7) ");
295       ADD_MEM (fpregs[27], 4);
296       ADD_STRING (" ");
297       ADD_MEM (fpregs[27], 8);
298       ADD_MEM (fpregs[28], 8);
299 
300       ADD_STRING ("\n mxcsr: ");
301       ADD_MEM (fpregs[29], 4);
302 
303       ADD_STRING ("\n XMM0:  ");
304       ADD_MEM (xmmregs[0], 32);
305       ADD_STRING (" XMM1:  ");
306       ADD_MEM (xmmregs[0], 32);
307       ADD_STRING ("\n XMM2:  ");
308       ADD_MEM (xmmregs[0], 32);
309       ADD_STRING (" XMM3:  ");
310       ADD_MEM (xmmregs[0], 32);
311       ADD_STRING ("\n XMM4:  ");
312       ADD_MEM (xmmregs[0], 32);
313       ADD_STRING (" XMM5:  ");
314       ADD_MEM (xmmregs[0], 32);
315       ADD_STRING ("\n XMM6:  ");
316       ADD_MEM (xmmregs[0], 32);
317       ADD_STRING (" XMM7:  ");
318       ADD_MEM (xmmregs[0], 32);
319       ADD_STRING ("\n XMM8:  ");
320       ADD_MEM (xmmregs[0], 32);
321       ADD_STRING (" XMM9:  ");
322       ADD_MEM (xmmregs[0], 32);
323       ADD_STRING ("\n XMM10: ");
324       ADD_MEM (xmmregs[0], 32);
325       ADD_STRING (" XMM11: ");
326       ADD_MEM (xmmregs[0], 32);
327       ADD_STRING ("\n XMM12: ");
328       ADD_MEM (xmmregs[0], 32);
329       ADD_STRING (" XMM13: ");
330       ADD_MEM (xmmregs[0], 32);
331       ADD_STRING ("\n XMM14: ");
332       ADD_MEM (xmmregs[0], 32);
333       ADD_STRING (" XMM15: ");
334       ADD_MEM (xmmregs[0], 32);
335 
336     }
337 
338   ADD_STRING ("\n");
339 
340   /* Write the stuff out.  */
341   writev (fd, iov, nr);
342 }
343 
344 
345 #define REGISTER_DUMP register_dump (fd, ctx)
346