2.9
[glibc/nacl-glibc.git] / sysdeps / unix / sysv / linux / x86_64 / register-dump.h
blob50f589d0d2901c77241f9b5d8ed3d5a19f39971d
1 /* Dump registers.
2 Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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. */
20 #include <sys/uio.h>
21 #include <stdio-common/_itoa.h>
23 /* We will print the register dump in this format:
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
32 RIP: XXXXXXXXXXXXXXXX EFLAGS: XXXXXXXX
34 CS: XXXX DS: XXXX ES: XXXX FS: XXXX GS: XXXX
36 Trap: XXXXXXXX Error: XXXXXXXX OldMask: XXXXXXXX
37 RSP/SIGNAL: XXXXXXXXXXXXXXXX CR2: XXXXXXXX
39 FPUCW: XXXXXXXX FPUSW: XXXXXXXX TAG: XXXXXXXX
40 IPOFF: XXXXXXXX CSSEL: XXXX DATAOFF: XXXXXXXX DATASEL: XXXX
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
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
59 static void
60 hexvalue (unsigned long int value, char *buf, size_t len)
62 char *cp = _itoa_word (value, buf + len, 16, 0);
63 while (cp > buf)
64 *--cp = '0';
67 static void
68 register_dump (int fd, struct ucontext *ctx)
70 char regs[25][16];
71 char fpregs[30][8];
72 char xmmregs[16][32];
73 struct iovec iov[147];
74 size_t nr = 0;
75 int i;
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
86 /* Generate strings of register contents. */
87 hexvalue (ctx->uc_mcontext.gregs[REG_RAX], regs[0], 16);
88 hexvalue (ctx->uc_mcontext.gregs[REG_RBX], regs[1], 16);
89 hexvalue (ctx->uc_mcontext.gregs[REG_RCX], regs[2], 16);
90 hexvalue (ctx->uc_mcontext.gregs[REG_RDX], regs[3], 16);
91 hexvalue (ctx->uc_mcontext.gregs[REG_RSI], regs[4], 16);
92 hexvalue (ctx->uc_mcontext.gregs[REG_RDI], regs[5], 16);
93 hexvalue (ctx->uc_mcontext.gregs[REG_RBP], regs[6], 16);
94 hexvalue (ctx->uc_mcontext.gregs[REG_R8], regs[7], 16);
95 hexvalue (ctx->uc_mcontext.gregs[REG_R9], regs[8], 16);
96 hexvalue (ctx->uc_mcontext.gregs[REG_R10], regs[9], 16);
97 hexvalue (ctx->uc_mcontext.gregs[REG_R11], regs[10], 16);
98 hexvalue (ctx->uc_mcontext.gregs[REG_R12], regs[11], 16);
99 hexvalue (ctx->uc_mcontext.gregs[REG_R13], regs[12], 16);
100 hexvalue (ctx->uc_mcontext.gregs[REG_R14], regs[13], 16);
101 hexvalue (ctx->uc_mcontext.gregs[REG_R15], regs[14], 16);
102 hexvalue (ctx->uc_mcontext.gregs[REG_RSP], regs[15], 16);
103 hexvalue (ctx->uc_mcontext.gregs[REG_RIP], regs[16], 16);
105 hexvalue (ctx->uc_mcontext.gregs[REG_EFL], regs[17], 8);
106 hexvalue (ctx->uc_mcontext.gregs[REG_CSGSFS] & 0xffff, regs[18], 4);
107 hexvalue ((ctx->uc_mcontext.gregs[REG_CSGSFS] >> 16) & 0xffff, regs[19], 4);
108 hexvalue ((ctx->uc_mcontext.gregs[REG_CSGSFS] >> 32) & 0xffff, regs[20], 4);
109 /* hexvalue (ctx->ss, regs[23], 4); */
110 hexvalue (ctx->uc_mcontext.gregs[REG_TRAPNO], regs[21], 8);
111 hexvalue (ctx->uc_mcontext.gregs[REG_ERR], regs[22], 8);
112 hexvalue (ctx->uc_mcontext.gregs[REG_OLDMASK], regs[23], 8);
113 hexvalue (ctx->uc_mcontext.gregs[REG_CR2], regs[24], 8);
115 /* Generate the output. */
116 ADD_STRING ("Register dump:\n\n RAX: ");
117 ADD_MEM (regs[0], 16);
118 ADD_STRING (" RBX: ");
119 ADD_MEM (regs[1], 16);
120 ADD_STRING (" RCX: ");
121 ADD_MEM (regs[2], 16);
122 ADD_STRING ("\n RDX: ");
123 ADD_MEM (regs[3], 16);
124 ADD_STRING (" RSI: ");
125 ADD_MEM (regs[4], 16);
126 ADD_STRING (" RDI: ");
127 ADD_MEM (regs[5], 16);
128 ADD_STRING ("\n RBP: ");
129 ADD_MEM (regs[6], 16);
130 ADD_STRING (" R8 : ");
131 ADD_MEM (regs[7], 16);
132 ADD_STRING (" R9 : ");
133 ADD_MEM (regs[8], 16);
134 ADD_STRING ("\n R10: ");
135 ADD_MEM (regs[9], 16);
136 ADD_STRING (" R11: ");
137 ADD_MEM (regs[10], 16);
138 ADD_STRING (" R12: ");
139 ADD_MEM (regs[11], 16);
140 ADD_STRING ("\n R13: ");
141 ADD_MEM (regs[12], 16);
142 ADD_STRING (" R14: ");
143 ADD_MEM (regs[13], 16);
144 ADD_STRING (" R15: ");
145 ADD_MEM (regs[14], 16);
146 ADD_STRING ("\n RSP: ");
147 ADD_MEM (regs[15], 16);
148 ADD_STRING ("\n\n RIP: ");
149 ADD_MEM (regs[16], 16);
150 ADD_STRING (" EFLAGS: ");
151 ADD_MEM (regs[17], 8);
152 ADD_STRING ("\n\n CS: ");
153 ADD_MEM (regs[18], 4);
154 ADD_STRING (" FS: ");
155 ADD_MEM (regs[19], 4);
156 ADD_STRING (" GS: ");
157 ADD_MEM (regs[20], 4);
159 ADD_STRING (" SS: ");
160 ADD_MEM (regs[23], 4);
162 ADD_STRING ("\n\n Trap: ");
163 ADD_MEM (regs[21], 8);
164 ADD_STRING (" Error: ");
165 ADD_MEM (regs[22], 8);
166 ADD_STRING (" OldMask: ");
167 ADD_MEM (regs[23], 8);
168 ADD_STRING (" CR2: ");
169 ADD_MEM (regs[24], 8);
171 if (ctx->uc_mcontext.fpregs != NULL)
174 /* Generate output for the FPU control/status registers. */
175 hexvalue (ctx->uc_mcontext.fpregs->cwd, fpregs[0], 8);
176 hexvalue (ctx->uc_mcontext.fpregs->swd, fpregs[1], 8);
177 hexvalue (ctx->uc_mcontext.fpregs->ftw, fpregs[2], 8);
178 hexvalue (ctx->uc_mcontext.fpregs->rip, fpregs[3], 8);
179 hexvalue (ctx->uc_mcontext.fpregs->rdp, fpregs[4], 8);
181 ADD_STRING ("\n\n FPUCW: ");
182 ADD_MEM (fpregs[0], 8);
183 ADD_STRING (" FPUSW: ");
184 ADD_MEM (fpregs[1], 8);
185 ADD_STRING (" TAG: ");
186 ADD_MEM (fpregs[2], 8);
187 ADD_STRING ("\n RIP: ");
188 ADD_MEM (fpregs[3], 8);
189 ADD_STRING (" RDP: ");
190 ADD_MEM (fpregs[4], 8);
192 /* Now the real FPU registers. */
193 hexvalue (ctx->uc_mcontext.fpregs->_st[0].exponent, fpregs[5], 8);
194 hexvalue (ctx->uc_mcontext.fpregs->_st[0].significand[3] << 16
195 | ctx->uc_mcontext.fpregs->_st[0].significand[2], fpregs[6],
197 hexvalue (ctx->uc_mcontext.fpregs->_st[0].significand[1] << 16
198 | ctx->uc_mcontext.fpregs->_st[0].significand[0], fpregs[7],
200 hexvalue (ctx->uc_mcontext.fpregs->_st[1].exponent, fpregs[8], 8);
201 hexvalue (ctx->uc_mcontext.fpregs->_st[1].significand[3] << 16
202 | ctx->uc_mcontext.fpregs->_st[1].significand[2], fpregs[9],
204 hexvalue (ctx->uc_mcontext.fpregs->_st[1].significand[1] << 16
205 | ctx->uc_mcontext.fpregs->_st[1].significand[0], fpregs[10],
207 hexvalue (ctx->uc_mcontext.fpregs->_st[2].exponent, fpregs[11], 8);
208 hexvalue (ctx->uc_mcontext.fpregs->_st[2].significand[3] << 16
209 | ctx->uc_mcontext.fpregs->_st[2].significand[2], fpregs[12],
211 hexvalue (ctx->uc_mcontext.fpregs->_st[2].significand[1] << 16
212 | ctx->uc_mcontext.fpregs->_st[2].significand[0], fpregs[13],
214 hexvalue (ctx->uc_mcontext.fpregs->_st[3].exponent, fpregs[14], 8);
215 hexvalue (ctx->uc_mcontext.fpregs->_st[3].significand[3] << 16
216 | ctx->uc_mcontext.fpregs->_st[3].significand[2], fpregs[15],
218 hexvalue (ctx->uc_mcontext.fpregs->_st[3].significand[1] << 16
219 | ctx->uc_mcontext.fpregs->_st[3].significand[0], fpregs[16],
221 hexvalue (ctx->uc_mcontext.fpregs->_st[4].exponent, fpregs[17], 8);
222 hexvalue (ctx->uc_mcontext.fpregs->_st[4].significand[3] << 16
223 | ctx->uc_mcontext.fpregs->_st[4].significand[2], fpregs[18],
225 hexvalue (ctx->uc_mcontext.fpregs->_st[4].significand[1] << 16
226 | ctx->uc_mcontext.fpregs->_st[4].significand[0], fpregs[19],
228 hexvalue (ctx->uc_mcontext.fpregs->_st[5].exponent, fpregs[20], 8);
229 hexvalue (ctx->uc_mcontext.fpregs->_st[5].significand[3] << 16
230 | ctx->uc_mcontext.fpregs->_st[5].significand[2], fpregs[21],
232 hexvalue (ctx->uc_mcontext.fpregs->_st[5].significand[1] << 16
233 | ctx->uc_mcontext.fpregs->_st[5].significand[0], fpregs[22],
235 hexvalue (ctx->uc_mcontext.fpregs->_st[6].exponent, fpregs[23], 8);
236 hexvalue (ctx->uc_mcontext.fpregs->_st[6].significand[3] << 16
237 | ctx->uc_mcontext.fpregs->_st[6].significand[2], fpregs[24],
239 hexvalue (ctx->uc_mcontext.fpregs->_st[6].significand[1] << 16
240 | ctx->uc_mcontext.fpregs->_st[6].significand[0], fpregs[25],
242 hexvalue (ctx->uc_mcontext.fpregs->_st[7].exponent, fpregs[26], 8);
243 hexvalue (ctx->uc_mcontext.fpregs->_st[7].significand[3] << 16
244 | ctx->uc_mcontext.fpregs->_st[7].significand[2], fpregs[27],
246 hexvalue (ctx->uc_mcontext.fpregs->_st[7].significand[1] << 16
247 | ctx->uc_mcontext.fpregs->_st[7].significand[0], fpregs[28],
250 hexvalue (ctx->uc_mcontext.fpregs->mxcsr, fpregs[29], 4);
252 for (i = 0; i < 16; i++)
253 hexvalue (ctx->uc_mcontext.fpregs->_xmm[i].element[3] << 24
254 | ctx->uc_mcontext.fpregs->_xmm[i].element[2] << 16
255 | ctx->uc_mcontext.fpregs->_xmm[i].element[1] << 8
256 | ctx->uc_mcontext.fpregs->_xmm[i].element[0], xmmregs[i],
257 32);
260 ADD_STRING ("\n\n ST(0) ");
261 ADD_MEM (fpregs[5], 4);
262 ADD_STRING (" ");
263 ADD_MEM (fpregs[6], 8);
264 ADD_MEM (fpregs[7], 8);
265 ADD_STRING (" ST(1) ");
266 ADD_MEM (fpregs[8], 4);
267 ADD_STRING (" ");
268 ADD_MEM (fpregs[9], 8);
269 ADD_MEM (fpregs[10], 8);
270 ADD_STRING ("\n ST(2) ");
271 ADD_MEM (fpregs[11], 4);
272 ADD_STRING (" ");
273 ADD_MEM (fpregs[12], 8);
274 ADD_MEM (fpregs[13], 8);
275 ADD_STRING (" ST(3) ");
276 ADD_MEM (fpregs[14], 4);
277 ADD_STRING (" ");
278 ADD_MEM (fpregs[15], 8);
279 ADD_MEM (fpregs[16], 8);
280 ADD_STRING ("\n ST(4) ");
281 ADD_MEM (fpregs[17], 4);
282 ADD_STRING (" ");
283 ADD_MEM (fpregs[18], 8);
284 ADD_MEM (fpregs[19], 8);
285 ADD_STRING (" ST(5) ");
286 ADD_MEM (fpregs[20], 4);
287 ADD_STRING (" ");
288 ADD_MEM (fpregs[21], 8);
289 ADD_MEM (fpregs[22], 8);
290 ADD_STRING ("\n ST(6) ");
291 ADD_MEM (fpregs[23], 4);
292 ADD_STRING (" ");
293 ADD_MEM (fpregs[24], 8);
294 ADD_MEM (fpregs[25], 8);
295 ADD_STRING (" ST(7) ");
296 ADD_MEM (fpregs[27], 4);
297 ADD_STRING (" ");
298 ADD_MEM (fpregs[27], 8);
299 ADD_MEM (fpregs[28], 8);
301 ADD_STRING ("\n mxcsr: ");
302 ADD_MEM (fpregs[29], 4);
304 ADD_STRING ("\n XMM0: ");
305 ADD_MEM (xmmregs[0], 32);
306 ADD_STRING (" XMM1: ");
307 ADD_MEM (xmmregs[0], 32);
308 ADD_STRING ("\n XMM2: ");
309 ADD_MEM (xmmregs[0], 32);
310 ADD_STRING (" XMM3: ");
311 ADD_MEM (xmmregs[0], 32);
312 ADD_STRING ("\n XMM4: ");
313 ADD_MEM (xmmregs[0], 32);
314 ADD_STRING (" XMM5: ");
315 ADD_MEM (xmmregs[0], 32);
316 ADD_STRING ("\n XMM6: ");
317 ADD_MEM (xmmregs[0], 32);
318 ADD_STRING (" XMM7: ");
319 ADD_MEM (xmmregs[0], 32);
320 ADD_STRING ("\n XMM8: ");
321 ADD_MEM (xmmregs[0], 32);
322 ADD_STRING (" XMM9: ");
323 ADD_MEM (xmmregs[0], 32);
324 ADD_STRING ("\n XMM10: ");
325 ADD_MEM (xmmregs[0], 32);
326 ADD_STRING (" XMM11: ");
327 ADD_MEM (xmmregs[0], 32);
328 ADD_STRING ("\n XMM12: ");
329 ADD_MEM (xmmregs[0], 32);
330 ADD_STRING (" XMM13: ");
331 ADD_MEM (xmmregs[0], 32);
332 ADD_STRING ("\n XMM14: ");
333 ADD_MEM (xmmregs[0], 32);
334 ADD_STRING (" XMM15: ");
335 ADD_MEM (xmmregs[0], 32);
339 ADD_STRING ("\n");
341 /* Write the stuff out. */
342 writev (fd, iov, nr);
346 #define REGISTER_DUMP register_dump (fd, ctx)