1 /* Dump registers.
2    Copyright (C) 1998-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  EAX: XXXXXXXX   EBX: XXXXXXXX   ECX: XXXXXXXX   EDX: XXXXXXXX
25  ESI: XXXXXXXX   EDI: XXXXXXXX   EBP: XXXXXXXX   ESP: XXXXXXXX
26 
27  EIP: XXXXXXXX   EFLAGS: XXXXXXXX
28 
29  CS:  XXXX   DS: XXXX   ES: XXXX   FS: XXXX   GS: XXXX   SS: XXXX
30 
31  Trap:  XXXXXXXX   Error: XXXXXXXX   OldMask: XXXXXXXX
32  ESP/SIGNAL: XXXXXXXX   CR2: XXXXXXXX
33 
34  FPUCW: XXXXXXXX   FPUSW: XXXXXXXX   TAG: XXXXXXXX
35  IPOFF: XXXXXXXX   CSSEL: XXXX   DATAOFF: XXXXXXXX   DATASEL: XXXX
36 
37  ST(0) XXXX XXXXXXXXXXXXXXXX   ST(1) XXXX XXXXXXXXXXXXXXXX
38  ST(2) XXXX XXXXXXXXXXXXXXXX   ST(3) XXXX XXXXXXXXXXXXXXXX
39  ST(4) XXXX XXXXXXXXXXXXXXXX   ST(5) XXXX XXXXXXXXXXXXXXXX
40  ST(6) XXXX XXXXXXXXXXXXXXXX   ST(7) XXXX XXXXXXXXXXXXXXXX
41 
42  */
43 
44 static void
hexvalue(unsigned long int value,char * buf,size_t len)45 hexvalue (unsigned long int value, char *buf, size_t len)
46 {
47   char *cp = _itoa_word (value, buf + len, 16, 0);
48   while (cp > buf)
49     *--cp = '0';
50 }
51 
52 static void
register_dump(int fd,struct ucontext_t * ctx)53 register_dump (int fd, struct ucontext_t *ctx)
54 {
55   char regs[21][8];
56   char fpregs[31][8];
57   struct iovec iov[97];
58   size_t nr = 0;
59 
60 #define ADD_STRING(str) \
61   iov[nr].iov_base = (char *) str;					      \
62   iov[nr].iov_len = strlen (str);					      \
63   ++nr
64 #define ADD_MEM(str, len) \
65   iov[nr].iov_base = str;						      \
66   iov[nr].iov_len = len;						      \
67   ++nr
68 
69   /* Generate strings of register contents.  */
70   hexvalue (ctx->uc_mcontext.gregs[REG_EAX], regs[0], 8);
71   hexvalue (ctx->uc_mcontext.gregs[REG_EBX], regs[1], 8);
72   hexvalue (ctx->uc_mcontext.gregs[REG_ECX], regs[2], 8);
73   hexvalue (ctx->uc_mcontext.gregs[REG_EDX], regs[3], 8);
74   hexvalue (ctx->uc_mcontext.gregs[REG_ESI], regs[4], 8);
75   hexvalue (ctx->uc_mcontext.gregs[REG_EDI], regs[5], 8);
76   hexvalue (ctx->uc_mcontext.gregs[REG_EBP], regs[6], 8);
77   hexvalue (ctx->uc_mcontext.gregs[REG_ESP], regs[7], 8);
78   hexvalue (ctx->uc_mcontext.gregs[REG_EIP], regs[8], 8);
79   hexvalue (ctx->uc_flags, regs[9], 8);
80   hexvalue (ctx->uc_mcontext.gregs[REG_CS], regs[10], 4);
81   hexvalue (ctx->uc_mcontext.gregs[REG_DS], regs[11], 4);
82   hexvalue (ctx->uc_mcontext.gregs[REG_ES], regs[12], 4);
83   hexvalue (ctx->uc_mcontext.gregs[REG_FS], regs[13], 4);
84   hexvalue (ctx->uc_mcontext.gregs[REG_GS], regs[14], 4);
85   hexvalue (ctx->uc_mcontext.gregs[REG_SS], regs[15], 4);
86   hexvalue (ctx->uc_mcontext.gregs[REG_TRAPNO], regs[16], 8);
87   hexvalue (ctx->uc_mcontext.gregs[REG_ERR], regs[17], 8);
88   hexvalue (ctx->uc_mcontext.oldmask, regs[18], 8);
89   hexvalue (ctx->uc_mcontext.gregs[REG_UESP], regs[19], 8);
90   hexvalue (ctx->uc_mcontext.cr2, regs[20], 8);
91 
92   /* Generate the output.  */
93   ADD_STRING ("Register dump:\n\n EAX: ");
94   ADD_MEM (regs[0], 8);
95   ADD_STRING ("   EBX: ");
96   ADD_MEM (regs[1], 8);
97   ADD_STRING ("   ECX: ");
98   ADD_MEM (regs[2], 8);
99   ADD_STRING ("   EDX: ");
100   ADD_MEM (regs[3], 8);
101   ADD_STRING ("\n ESI: ");
102   ADD_MEM (regs[4], 8);
103   ADD_STRING ("   EDI: ");
104   ADD_MEM (regs[5], 8);
105   ADD_STRING ("   EBP: ");
106   ADD_MEM (regs[6], 8);
107   ADD_STRING ("   ESP: ");
108   ADD_MEM (regs[7], 8);
109   ADD_STRING ("\n\n EIP: ");
110   ADD_MEM (regs[8], 8);
111   ADD_STRING ("   EFLAGS: ");
112   ADD_MEM (regs[9], 8);
113   ADD_STRING ("\n\n CS: ");
114   ADD_MEM (regs[10], 4);
115   ADD_STRING ("   DS: ");
116   ADD_MEM (regs[11], 4);
117   ADD_STRING ("   ES: ");
118   ADD_MEM (regs[12], 4);
119   ADD_STRING ("   FS: ");
120   ADD_MEM (regs[13], 4);
121   ADD_STRING ("   GS: ");
122   ADD_MEM (regs[14], 4);
123   ADD_STRING ("   SS: ");
124   ADD_MEM (regs[15], 4);
125   ADD_STRING ("\n\n Trap: ");
126   ADD_MEM (regs[16], 8);
127   ADD_STRING ("   Error: ");
128   ADD_MEM (regs[17], 8);
129   ADD_STRING ("   OldMask: ");
130   ADD_MEM (regs[18], 8);
131   ADD_STRING ("\n ESP/signal: ");
132   ADD_MEM (regs[19], 8);
133   ADD_STRING ("   CR2: ");
134   ADD_MEM (regs[20], 8);
135 
136   /* Generate output for the FPU control/status registers.  */
137   hexvalue (ctx->__fpregs_mem.cw, fpregs[0], 8);
138   hexvalue (ctx->__fpregs_mem.sw, fpregs[1], 8);
139   hexvalue (ctx->__fpregs_mem.tag, fpregs[2], 8);
140   hexvalue (ctx->__fpregs_mem.ipoff, fpregs[3], 8);
141   hexvalue (ctx->__fpregs_mem.cssel, fpregs[4], 4);
142   hexvalue (ctx->__fpregs_mem.dataoff, fpregs[5], 8);
143   hexvalue (ctx->__fpregs_mem.datasel, fpregs[6], 4);
144 
145   ADD_STRING ("\n\n FPUCW: ");
146   ADD_MEM (fpregs[0], 8);
147   ADD_STRING ("   FPUSW: ");
148   ADD_MEM (fpregs[1], 8);
149   ADD_STRING ("   TAG: ");
150   ADD_MEM (fpregs[2], 8);
151   ADD_STRING ("\n IPOFF: ");
152   ADD_MEM (fpregs[3], 8);
153   ADD_STRING ("   CSSEL: ");
154   ADD_MEM (fpregs[4], 4);
155   ADD_STRING ("   DATAOFF: ");
156   ADD_MEM (fpregs[5], 8);
157   ADD_STRING ("   DATASEL: ");
158   ADD_MEM (fpregs[6], 4);
159 
160   /* Now the real FPU registers.  */
161   hexvalue (ctx->__fpregs_mem._st[0].exponent, fpregs[7], 8);
162   hexvalue (ctx->__fpregs_mem._st[0].significand[3] << 16
163 		| ctx->__fpregs_mem._st[0].significand[2], fpregs[8], 8);
164   hexvalue (ctx->__fpregs_mem._st[0].significand[1] << 16
165 		| ctx->__fpregs_mem._st[0].significand[0], fpregs[9], 8);
166   hexvalue (ctx->__fpregs_mem._st[1].exponent, fpregs[10], 8);
167   hexvalue (ctx->__fpregs_mem._st[1].significand[3] << 16
168 		| ctx->__fpregs_mem._st[1].significand[2], fpregs[11], 8);
169   hexvalue (ctx->__fpregs_mem._st[1].significand[1] << 16
170 		| ctx->__fpregs_mem._st[1].significand[0], fpregs[12], 8);
171   hexvalue (ctx->__fpregs_mem._st[2].exponent, fpregs[13], 8);
172   hexvalue (ctx->__fpregs_mem._st[2].significand[3] << 16
173 		| ctx->__fpregs_mem._st[2].significand[2], fpregs[14], 8);
174   hexvalue (ctx->__fpregs_mem._st[2].significand[1] << 16
175 		| ctx->__fpregs_mem._st[2].significand[0], fpregs[15], 8);
176   hexvalue (ctx->__fpregs_mem._st[3].exponent, fpregs[16], 8);
177   hexvalue (ctx->__fpregs_mem._st[3].significand[3] << 16
178 		| ctx->__fpregs_mem._st[3].significand[2], fpregs[17], 8);
179   hexvalue (ctx->__fpregs_mem._st[3].significand[1] << 16
180 		| ctx->__fpregs_mem._st[3].significand[0], fpregs[18], 8);
181   hexvalue (ctx->__fpregs_mem._st[4].exponent, fpregs[19], 8);
182   hexvalue (ctx->__fpregs_mem._st[4].significand[3] << 16
183 		| ctx->__fpregs_mem._st[4].significand[2], fpregs[20], 8);
184   hexvalue (ctx->__fpregs_mem._st[4].significand[1] << 16
185 		| ctx->__fpregs_mem._st[4].significand[0], fpregs[21], 8);
186   hexvalue (ctx->__fpregs_mem._st[5].exponent, fpregs[22], 8);
187   hexvalue (ctx->__fpregs_mem._st[5].significand[3] << 16
188 		| ctx->__fpregs_mem._st[5].significand[2], fpregs[23], 8);
189   hexvalue (ctx->__fpregs_mem._st[5].significand[1] << 16
190 		| ctx->__fpregs_mem._st[5].significand[0], fpregs[24], 8);
191   hexvalue (ctx->__fpregs_mem._st[6].exponent, fpregs[25], 8);
192   hexvalue (ctx->__fpregs_mem._st[6].significand[3] << 16
193 		| ctx->__fpregs_mem._st[6].significand[2], fpregs[26], 8);
194   hexvalue (ctx->__fpregs_mem._st[6].significand[1] << 16
195 		| ctx->__fpregs_mem._st[6].significand[0], fpregs[27], 8);
196   hexvalue (ctx->__fpregs_mem._st[7].exponent, fpregs[28], 8);
197   hexvalue (ctx->__fpregs_mem._st[7].significand[3] << 16
198 		| ctx->__fpregs_mem._st[7].significand[2], fpregs[29], 8);
199   hexvalue (ctx->__fpregs_mem._st[7].significand[1] << 16
200 		| ctx->__fpregs_mem._st[7].significand[0], fpregs[30], 8);
201 
202   ADD_STRING ("\n\n ST(0) ");
203   ADD_MEM (fpregs[7], 4);
204   ADD_STRING (" ");
205   ADD_MEM (fpregs[8], 8);
206   ADD_MEM (fpregs[9], 8);
207   ADD_STRING ("   ST(1) ");
208   ADD_MEM (fpregs[10], 4);
209   ADD_STRING (" ");
210   ADD_MEM (fpregs[11], 8);
211   ADD_MEM (fpregs[12], 8);
212   ADD_STRING ("\n ST(2) ");
213   ADD_MEM (fpregs[13], 4);
214   ADD_STRING (" ");
215   ADD_MEM (fpregs[14], 8);
216   ADD_MEM (fpregs[15], 8);
217   ADD_STRING ("   ST(3) ");
218   ADD_MEM (fpregs[16], 4);
219   ADD_STRING (" ");
220   ADD_MEM (fpregs[17], 8);
221   ADD_MEM (fpregs[18], 8);
222   ADD_STRING ("\n ST(4) ");
223   ADD_MEM (fpregs[19], 4);
224   ADD_STRING (" ");
225   ADD_MEM (fpregs[20], 8);
226   ADD_MEM (fpregs[21], 8);
227   ADD_STRING ("   ST(5) ");
228   ADD_MEM (fpregs[22], 4);
229   ADD_STRING (" ");
230   ADD_MEM (fpregs[23], 8);
231   ADD_MEM (fpregs[24], 8);
232   ADD_STRING ("\n ST(6) ");
233   ADD_MEM (fpregs[25], 4);
234   ADD_STRING (" ");
235   ADD_MEM (fpregs[26], 8);
236   ADD_MEM (fpregs[27], 8);
237   ADD_STRING ("   ST(7) ");
238   ADD_MEM (fpregs[28], 4);
239   ADD_STRING (" ");
240   ADD_MEM (fpregs[29], 8);
241   ADD_MEM (fpregs[30], 8);
242 
243   ADD_STRING ("\n");
244 
245   /* Write the stuff out.  */
246   writev (fd, iov, nr);
247 }
248 
249 
250 #define REGISTER_DUMP register_dump (fd, ctx)
251