1/* Dump registers.
2 Copyright (C) 2001-2016 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 <http://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
58static void
59hexvalue (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
66static void
67register_dump (int fd, struct ucontext *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