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