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 <stddef.h>
20 #include <sys/uio.h>
21 #include <_itoa.h>
22
23 /* We will print the register dump in this format:
24
25 D0: XXXXXXXX D1: XXXXXXXX D2: XXXXXXXX D3: XXXXXXXX
26 D4: XXXXXXXX D5: XXXXXXXX D6: XXXXXXXX D7: XXXXXXXX
27 A0: XXXXXXXX A1: XXXXXXXX A2: XXXXXXXX A3: XXXXXXXX
28 A4: XXXXXXXX A5: XXXXXXXX A6: XXXXXXXX A7: XXXXXXXX
29 PC: XXXXXXXX SR: XXXX
30
31 OldMask: XXXXXXXX Vector: XXXX
32
33 FP0: XXXXXXXXXXXXXXXXXXXXXXXX FP1: XXXXXXXXXXXXXXXXXXXXXXXX
34 FP2: XXXXXXXXXXXXXXXXXXXXXXXX FP3: XXXXXXXXXXXXXXXXXXXXXXXX
35 FP4: XXXXXXXXXXXXXXXXXXXXXXXX FP5: XXXXXXXXXXXXXXXXXXXXXXXX
36 FP6: XXXXXXXXXXXXXXXXXXXXXXXX FP7: XXXXXXXXXXXXXXXXXXXXXXXX
37 FPCR: XXXXXXXX FPSR: XXXXXXXX FPIAR: XXXXXXXX
38
39 */
40
41 #define FPCONTEXT_SIZE 216
42 #define uc_formatvec __glibc_reserved1[FPCONTEXT_SIZE/4]
43 #define uc_oldmask uc_sigmask.__val[0]
44
45 static void
hexvalue(unsigned long int value,char * buf,size_t len)46 hexvalue (unsigned long int value, char *buf, size_t len)
47 {
48 char *cp = _itoa_word (value, buf + len, 16, 0);
49 while (cp > buf)
50 *--cp = '0';
51 }
52
53 static void
register_dump(int fd,struct ucontext_t * ctx)54 register_dump (int fd, struct ucontext_t *ctx)
55 {
56 char regs[20][8];
57 char fpregs[11][24];
58 struct iovec iov[63], *next_iov = iov;
59 int i, j, fpreg_size;
60
61 #define ADD_STRING(str) \
62 next_iov->iov_base = (char *) (str); \
63 next_iov->iov_len = strlen (str); \
64 ++next_iov
65 #define ADD_MEM(str, len) \
66 next_iov->iov_base = (str); \
67 next_iov->iov_len = (len); \
68 ++next_iov
69
70 #ifdef __mcoldfire__
71 fpreg_size = 16;
72 #else
73 fpreg_size = 24;
74 #endif
75
76 /* Generate strings of register contents. */
77 hexvalue (ctx->uc_mcontext.gregs[R_D0], regs[0], 8);
78 hexvalue (ctx->uc_mcontext.gregs[R_D1], regs[1], 8);
79 hexvalue (ctx->uc_mcontext.gregs[R_D2], regs[2], 8);
80 hexvalue (ctx->uc_mcontext.gregs[R_D3], regs[3], 8);
81 hexvalue (ctx->uc_mcontext.gregs[R_D4], regs[4], 8);
82 hexvalue (ctx->uc_mcontext.gregs[R_D5], regs[5], 8);
83 hexvalue (ctx->uc_mcontext.gregs[R_D6], regs[6], 8);
84 hexvalue (ctx->uc_mcontext.gregs[R_D7], regs[7], 8);
85 hexvalue (ctx->uc_mcontext.gregs[R_A0], regs[8], 8);
86 hexvalue (ctx->uc_mcontext.gregs[R_A1], regs[9], 8);
87 hexvalue (ctx->uc_mcontext.gregs[R_A2], regs[10], 8);
88 hexvalue (ctx->uc_mcontext.gregs[R_A3], regs[11], 8);
89 hexvalue (ctx->uc_mcontext.gregs[R_A4], regs[12], 8);
90 hexvalue (ctx->uc_mcontext.gregs[R_A5], regs[13], 8);
91 hexvalue (ctx->uc_mcontext.gregs[R_A6], regs[14], 8);
92 hexvalue (ctx->uc_mcontext.gregs[R_SP], regs[15], 8);
93 hexvalue (ctx->uc_mcontext.gregs[R_PC], regs[16], 8);
94 hexvalue (ctx->uc_mcontext.gregs[R_PS], regs[17], 4);
95 hexvalue (ctx->uc_oldmask, regs[18], 8);
96 hexvalue (ctx->uc_formatvec & 0xfff, regs[19], 4);
97
98 for (i = 0; i < 8; i++)
99 for (j = 0; j < fpreg_size; j += 8)
100 hexvalue (ctx->uc_mcontext.fpregs.f_fpregs[i][j/8], fpregs[i] + j, 8);
101 hexvalue (ctx->uc_mcontext.fpregs.f_pcr, fpregs[8], 8);
102 hexvalue (ctx->uc_mcontext.fpregs.f_psr, fpregs[9], 8);
103 hexvalue (ctx->uc_mcontext.fpregs.f_fpiaddr, fpregs[10], 8);
104
105 /* Generate the output. */
106 ADD_STRING ("Register dump:\n\n D0: ");
107 ADD_MEM (regs[0], 8);
108 ADD_STRING (" D1: ");
109 ADD_MEM (regs[1], 8);
110 ADD_STRING (" D2: ");
111 ADD_MEM (regs[2], 8);
112 ADD_STRING (" D3: ");
113 ADD_MEM (regs[3], 8);
114 ADD_STRING ("\n D4: ");
115 ADD_MEM (regs[4], 8);
116 ADD_STRING (" D5: ");
117 ADD_MEM (regs[5], 8);
118 ADD_STRING (" D6: ");
119 ADD_MEM (regs[6], 8);
120 ADD_STRING (" D7: ");
121 ADD_MEM (regs[7], 8);
122 ADD_STRING ("\n A0: ");
123 ADD_MEM (regs[8], 8);
124 ADD_STRING (" A1: ");
125 ADD_MEM (regs[9], 8);
126 ADD_STRING (" A2: ");
127 ADD_MEM (regs[10], 8);
128 ADD_STRING (" A3: ");
129 ADD_MEM (regs[11], 8);
130 ADD_STRING ("\n A4: ");
131 ADD_MEM (regs[12], 8);
132 ADD_STRING (" A5: ");
133 ADD_MEM (regs[13], 8);
134 ADD_STRING (" A6: ");
135 ADD_MEM (regs[14], 8);
136 ADD_STRING (" A7: ");
137 ADD_MEM (regs[15], 8);
138 ADD_STRING ("\n PC: ");
139 ADD_MEM (regs[16], 8);
140 ADD_STRING (" SR: ");
141 ADD_MEM (regs[17], 4);
142
143 ADD_STRING ("\n\n OldMask: ");
144 ADD_MEM (regs[18], 8);
145 ADD_STRING (" Vector: ");
146 ADD_MEM (regs[19], 4);
147
148 ADD_STRING ("\n\n FP0: ");
149 ADD_MEM (fpregs[0], fpreg_size);
150 ADD_STRING (" FP1: ");
151 ADD_MEM (fpregs[1], fpreg_size);
152 ADD_STRING ("\n FP2: ");
153 ADD_MEM (fpregs[2], fpreg_size);
154 ADD_STRING (" FP3: ");
155 ADD_MEM (fpregs[3], fpreg_size);
156 ADD_STRING ("\n FP4: ");
157 ADD_MEM (fpregs[4], fpreg_size);
158 ADD_STRING (" FP5: ");
159 ADD_MEM (fpregs[5], fpreg_size);
160 ADD_STRING ("\n FP6: ");
161 ADD_MEM (fpregs[6], fpreg_size);
162 ADD_STRING (" FP7: ");
163 ADD_MEM (fpregs[7], fpreg_size);
164 ADD_STRING ("\n FPCR: ");
165 ADD_MEM (fpregs[8], 8);
166 ADD_STRING (" FPSR: ");
167 ADD_MEM (fpregs[9], 8);
168 ADD_STRING (" FPIAR: ");
169 ADD_MEM (fpregs[10], 8);
170 ADD_STRING ("\n");
171
172 /* Write the stuff out. */
173 writev (fd, iov, next_iov - iov);
174 }
175
176 #define REGISTER_DUMP register_dump (fd, ctx)
177