]>
Commit | Line | Data |
---|---|---|
f35b9f2a | 1 | /* Dump registers. |
b168057a | 2 | Copyright (C) 1998-2015 Free Software Foundation, Inc. |
f35b9f2a AS |
3 | This file is part of the GNU C Library. |
4 | Contributed by Andreas Schwab <schwab@gnu.org>. | |
5 | ||
6 | The GNU C Library is free software; you can redistribute it and/or | |
3214b89b AJ |
7 | modify it under the terms of the GNU Lesser General Public |
8 | License as published by the Free Software Foundation; either | |
9 | version 2.1 of the License, or (at your option) any later version. | |
f35b9f2a AS |
10 | |
11 | The GNU C Library is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
3214b89b | 14 | Lesser General Public License for more details. |
f35b9f2a | 15 | |
3214b89b | 16 | You should have received a copy of the GNU Lesser General Public |
ab84e3ff PE |
17 | License along with the GNU C Library. If not, see |
18 | <http://www.gnu.org/licenses/>. */ | |
f35b9f2a AS |
19 | |
20 | #include <stddef.h> | |
21 | #include <sys/uio.h> | |
57988d0b | 22 | #include <_itoa.h> |
f35b9f2a AS |
23 | |
24 | /* We will print the register dump in this format: | |
25 | ||
26 | D0: XXXXXXXX D1: XXXXXXXX D2: XXXXXXXX D3: XXXXXXXX | |
27 | D4: XXXXXXXX D5: XXXXXXXX D6: XXXXXXXX D7: XXXXXXXX | |
28 | A0: XXXXXXXX A1: XXXXXXXX A2: XXXXXXXX A3: XXXXXXXX | |
29 | A4: XXXXXXXX A5: XXXXXXXX A6: XXXXXXXX A7: XXXXXXXX | |
30 | PC: XXXXXXXX SR: XXXX | |
31 | ||
32 | OldMask: XXXXXXXX Vector: XXXX | |
33 | ||
34 | FP0: XXXXXXXXXXXXXXXXXXXXXXXX FP1: XXXXXXXXXXXXXXXXXXXXXXXX | |
35 | FP2: XXXXXXXXXXXXXXXXXXXXXXXX FP3: XXXXXXXXXXXXXXXXXXXXXXXX | |
36 | FP4: XXXXXXXXXXXXXXXXXXXXXXXX FP5: XXXXXXXXXXXXXXXXXXXXXXXX | |
37 | FP6: XXXXXXXXXXXXXXXXXXXXXXXX FP7: XXXXXXXXXXXXXXXXXXXXXXXX | |
38 | FPCR: XXXXXXXX FPSR: XXXXXXXX FPIAR: XXXXXXXX | |
39 | ||
40 | */ | |
41 | ||
42 | /* Linux saves only the call-clobbered registers in the sigcontext. We | |
43 | need to use a trampoline that saves the rest so that the C code can | |
44 | access them. We use the sc_fpstate field, since the handler is not | |
45 | supposed to return anyway, thus it doesn't matter that it's clobbered. */ | |
46 | ||
47 | /* static */ void catch_segfault (int, int, struct sigcontext *); | |
48 | ||
49 | /* Dummy function so that we can use asm with arguments. */ | |
e52ded18 | 50 | static void __attribute_used__ |
f35b9f2a AS |
51 | __dummy__ (void) |
52 | { | |
bbb3856d UD |
53 | asm ("\n\ |
54 | catch_segfault:\n\ | |
55 | move.l 12(%%sp),%%a0\n\ | |
56 | lea %c0(%%a0),%%a0\n\ | |
57 | /* Clear the first 4 bytes to make it a null fp state, just\n\ | |
58 | in case the handler does return. */\n\ | |
59 | clr.l (%%a0)+\n\ | |
75e73e66 MK |
60 | movem.l %%d2-%%d7/%%a2-%%a6,(%%a0)\n" |
61 | #ifndef __mcoldfire__ | |
62 | "fmovem.x %%fp2-%%fp7,11*4(%%a0)\n" | |
63 | #elif defined __mcffpu__ | |
64 | "fmovem.d %%fp2-%%fp7,11*4(%%a0)\n" | |
65 | #endif | |
66 | "jra real_catch_segfault" | |
f35b9f2a AS |
67 | : : "n" (offsetof (struct sigcontext, sc_fpstate))); |
68 | } | |
69 | #define catch_segfault(a,b) \ | |
e52ded18 | 70 | __attribute_used__ real_catch_segfault(a,b) |
f35b9f2a AS |
71 | |
72 | static void | |
73 | hexvalue (unsigned long int value, char *buf, size_t len) | |
74 | { | |
75 | char *cp = _itoa_word (value, buf + len, 16, 0); | |
76 | while (cp > buf) | |
77 | *--cp = '0'; | |
78 | } | |
79 | ||
80 | static void | |
81 | register_dump (int fd, struct sigcontext *ctx) | |
82 | { | |
83 | char regs[20][8]; | |
84 | char fpregs[11][24]; | |
85 | struct iovec iov[63], *next_iov = iov; | |
86 | unsigned long *p = (unsigned long *) ctx->sc_fpstate + 1; | |
9c986f87 AS |
87 | unsigned long *pfp = (unsigned long *) ctx->sc_fpregs; |
88 | int i, j, fpreg_size; | |
f35b9f2a AS |
89 | |
90 | #define ADD_STRING(str) \ | |
91 | next_iov->iov_base = (char *) (str); \ | |
92 | next_iov->iov_len = strlen (str); \ | |
93 | ++next_iov | |
94 | #define ADD_MEM(str, len) \ | |
95 | next_iov->iov_base = (str); \ | |
96 | next_iov->iov_len = (len); \ | |
97 | ++next_iov | |
98 | ||
9c986f87 AS |
99 | #ifdef __mcoldfire__ |
100 | fpreg_size = 16; | |
101 | #else | |
102 | fpreg_size = 24; | |
103 | #endif | |
104 | ||
f35b9f2a AS |
105 | /* Generate strings of register contents. */ |
106 | hexvalue (ctx->sc_d0, regs[0], 8); | |
107 | hexvalue (ctx->sc_d1, regs[1], 8); | |
108 | hexvalue (*p++, regs[2], 8); | |
109 | hexvalue (*p++, regs[3], 8); | |
110 | hexvalue (*p++, regs[4], 8); | |
111 | hexvalue (*p++, regs[5], 8); | |
112 | hexvalue (*p++, regs[6], 8); | |
113 | hexvalue (*p++, regs[7], 8); | |
114 | hexvalue (ctx->sc_a0, regs[8], 8); | |
115 | hexvalue (ctx->sc_a1, regs[9], 8); | |
116 | hexvalue (*p++, regs[10], 8); | |
117 | hexvalue (*p++, regs[11], 8); | |
118 | hexvalue (*p++, regs[12], 8); | |
119 | hexvalue (*p++, regs[13], 8); | |
120 | hexvalue (*p++, regs[14], 8); | |
121 | hexvalue (ctx->sc_usp, regs[15], 8); | |
122 | hexvalue (ctx->sc_pc, regs[16], 8); | |
123 | hexvalue (ctx->sc_sr, regs[17], 4); | |
124 | hexvalue (ctx->sc_mask, regs[18], 8); | |
125 | hexvalue (ctx->sc_formatvec & 0xfff, regs[19], 4); | |
9c986f87 AS |
126 | for (i = 0; i < 2; i++) |
127 | for (j = 0; j < fpreg_size; j += 8) | |
128 | hexvalue (*pfp++, fpregs[i] + j, 8); | |
9c986f87 AS |
129 | for (i = 2; i < 8; i++) |
130 | for (j = 0; j < fpreg_size; j += 8) | |
131 | hexvalue (*p++, fpregs[i] + j, 8); | |
f35b9f2a AS |
132 | hexvalue (ctx->sc_fpcntl[0], fpregs[8], 8); |
133 | hexvalue (ctx->sc_fpcntl[1], fpregs[9], 8); | |
134 | hexvalue (ctx->sc_fpcntl[2], fpregs[10], 8); | |
135 | ||
136 | /* Generate the output. */ | |
137 | ADD_STRING ("Register dump:\n\n D0: "); | |
138 | ADD_MEM (regs[0], 8); | |
139 | ADD_STRING (" D1: "); | |
140 | ADD_MEM (regs[1], 8); | |
141 | ADD_STRING (" D2: "); | |
142 | ADD_MEM (regs[2], 8); | |
143 | ADD_STRING (" D3: "); | |
144 | ADD_MEM (regs[3], 8); | |
145 | ADD_STRING ("\n D4: "); | |
146 | ADD_MEM (regs[4], 8); | |
147 | ADD_STRING (" D5: "); | |
148 | ADD_MEM (regs[5], 8); | |
149 | ADD_STRING (" D6: "); | |
150 | ADD_MEM (regs[6], 8); | |
151 | ADD_STRING (" D7: "); | |
152 | ADD_MEM (regs[7], 8); | |
153 | ADD_STRING ("\n A0: "); | |
154 | ADD_MEM (regs[8], 8); | |
155 | ADD_STRING (" A1: "); | |
156 | ADD_MEM (regs[9], 8); | |
157 | ADD_STRING (" A2: "); | |
158 | ADD_MEM (regs[10], 8); | |
159 | ADD_STRING (" A3: "); | |
160 | ADD_MEM (regs[11], 8); | |
161 | ADD_STRING ("\n A4: "); | |
162 | ADD_MEM (regs[12], 8); | |
163 | ADD_STRING (" A5: "); | |
164 | ADD_MEM (regs[13], 8); | |
165 | ADD_STRING (" A6: "); | |
166 | ADD_MEM (regs[14], 8); | |
167 | ADD_STRING (" A7: "); | |
168 | ADD_MEM (regs[15], 8); | |
169 | ADD_STRING ("\n PC: "); | |
170 | ADD_MEM (regs[16], 8); | |
171 | ADD_STRING (" SR: "); | |
172 | ADD_MEM (regs[17], 4); | |
173 | ||
174 | ADD_STRING ("\n\n OldMask: "); | |
175 | ADD_MEM (regs[18], 8); | |
176 | ADD_STRING (" Vector: "); | |
177 | ADD_MEM (regs[19], 4); | |
178 | ||
179 | ADD_STRING ("\n\n FP0: "); | |
9c986f87 | 180 | ADD_MEM (fpregs[0], fpreg_size); |
f35b9f2a | 181 | ADD_STRING (" FP1: "); |
9c986f87 | 182 | ADD_MEM (fpregs[1], fpreg_size); |
f35b9f2a | 183 | ADD_STRING ("\n FP2: "); |
9c986f87 | 184 | ADD_MEM (fpregs[2], fpreg_size); |
f35b9f2a | 185 | ADD_STRING (" FP3: "); |
9c986f87 | 186 | ADD_MEM (fpregs[3], fpreg_size); |
f35b9f2a | 187 | ADD_STRING ("\n FP4: "); |
9c986f87 | 188 | ADD_MEM (fpregs[4], fpreg_size); |
f35b9f2a | 189 | ADD_STRING (" FP5: "); |
9c986f87 | 190 | ADD_MEM (fpregs[5], fpreg_size); |
f35b9f2a | 191 | ADD_STRING ("\n FP6: "); |
9c986f87 | 192 | ADD_MEM (fpregs[6], fpreg_size); |
f35b9f2a | 193 | ADD_STRING (" FP7: "); |
9c986f87 | 194 | ADD_MEM (fpregs[7], fpreg_size); |
f35b9f2a AS |
195 | ADD_STRING ("\n FPCR: "); |
196 | ADD_MEM (fpregs[8], 8); | |
197 | ADD_STRING (" FPSR: "); | |
198 | ADD_MEM (fpregs[9], 8); | |
199 | ADD_STRING (" FPIAR: "); | |
200 | ADD_MEM (fpregs[10], 8); | |
201 | ADD_STRING ("\n"); | |
202 | ||
203 | /* Write the stuff out. */ | |
204 | writev (fd, iov, next_iov - iov); | |
205 | } | |
206 | ||
207 | #define REGISTER_DUMP register_dump (fd, ctx) |