]>
Commit | Line | Data |
---|---|---|
d5efd131 | 1 | /* Dump registers. |
04277e02 | 2 | Copyright (C) 2004-2019 Free Software Foundation, Inc. |
d5efd131 MF |
3 | This file is part of the GNU C Library. |
4 | Contributed by Jakub Jelinek <jakub@redhat.com>, 2004. | |
5 | ||
6 | The GNU C Library is free software; you can redistribute it and/or | |
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. | |
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 | |
14 | Lesser General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU Lesser General Public | |
75efb018 MF |
17 | License along with the GNU C Library; if not, see |
18 | <http://www.gnu.org/licenses/>. */ | |
d5efd131 MF |
19 | |
20 | #include <string.h> | |
21 | #include <sys/uio.h> | |
6eeb0e8f | 22 | #include <_itoa.h> |
d5efd131 MF |
23 | |
24 | /* We will print the register dump in this format: | |
25 | ||
26 | GP: XXXXXXXXXXXXXXXX R2: XXXXXXXXXXXXXXXX R3: XXXXXXXXXXXXXXXX | |
27 | R8: XXXXXXXXXXXXXXXX R9: XXXXXXXXXXXXXXXX R10: XXXXXXXXXXXXXXXX | |
28 | R11: XXXXXXXXXXXXXXXX SP: XXXXXXXXXXXXXXXX TP: XXXXXXXXXXXXXXXX | |
29 | R14: XXXXXXXXXXXXXXXX R15: XXXXXXXXXXXXXXXX R16: XXXXXXXXXXXXXXXX | |
30 | R17: XXXXXXXXXXXXXXXX R18: XXXXXXXXXXXXXXXX R19: XXXXXXXXXXXXXXXX | |
31 | R20: XXXXXXXXXXXXXXXX R21: XXXXXXXXXXXXXXXX R22: XXXXXXXXXXXXXXXX | |
32 | R23: XXXXXXXXXXXXXXXX R24: XXXXXXXXXXXXXXXX R25: XXXXXXXXXXXXXXXX | |
33 | R26: XXXXXXXXXXXXXXXX R27: XXXXXXXXXXXXXXXX R28: XXXXXXXXXXXXXXXX | |
34 | R29: XXXXXXXXXXXXXXXX R30: XXXXXXXXXXXXXXXX R31: XXXXXXXXXXXXXXXX | |
35 | ||
36 | RP: XXXXXXXXXXXXXXXX B6: XXXXXXXXXXXXXXXX B7: XXXXXXXXXXXXXXXX | |
37 | ||
38 | IP: XXXXXXXXXXXXXXXX RSC: XXXXXXXXXXXXXXXX PR: XXXXXXXXXXXXXXXX | |
39 | PFS: XXXXXXXXXXXXXXXX UNAT: XXXXXXXXXXXXXXXX CFM: XXXXXXXXXXXXXXXX | |
40 | CCV: XXXXXXXXXXXXXXXX FPSR: XXXXXXXXXXXXXXXX | |
41 | ||
42 | F32: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX F33: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
43 | F34: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX F35: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
44 | ... | |
45 | F124: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX F125: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
46 | F126: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX F127: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
47 | */ | |
48 | ||
49 | static void | |
50 | hexvalue (unsigned long int value, char *buf, size_t len) | |
51 | { | |
52 | char *cp = _itoa_word (value, buf + len, 16, 0); | |
53 | while (cp > buf) | |
54 | *--cp = '0'; | |
55 | } | |
56 | ||
57 | static void | |
58 | regvalue (unsigned long int *value, char letter, int regno, char *buf) | |
59 | { | |
60 | int n = regno >= 100 ? 3 : regno >= 10 ? 2 : 1; | |
61 | buf[0] = ' '; | |
62 | buf[1] = letter; | |
63 | _itoa_word (regno, buf + 2 + n, 10, 0); | |
64 | buf[2 + n] = ':'; | |
65 | for (++n; n <= 4; ++n) | |
66 | buf[2 + n] = ' '; | |
67 | hexvalue (value[0], buf + 7, 16); | |
68 | if (letter == 'F') | |
69 | { | |
70 | hexvalue (value[1], buf + 7 + 16, 16); | |
71 | buf[7 + 32] = '\n'; | |
72 | } | |
73 | else | |
74 | buf[7 + 16] = '\n'; | |
75 | } | |
76 | ||
77 | static void | |
78 | register_dump (int fd, struct sigcontext *ctx) | |
79 | { | |
80 | char gpregs[32 - 5][8 + 16]; | |
81 | char fpregs[128 - 32][8 + 32]; | |
82 | char bpregs[3][8 + 16]; | |
83 | char spregs[8][16]; | |
84 | struct iovec iov[146]; | |
85 | size_t nr = 0; | |
86 | int i; | |
87 | ||
88 | #define ADD_STRING(str) \ | |
89 | do \ | |
90 | { \ | |
91 | iov[nr].iov_base = (char *) str; \ | |
92 | iov[nr].iov_len = strlen (str); \ | |
93 | ++nr; \ | |
94 | } \ | |
95 | while (0) | |
96 | #define ADD_MEM(str, len) \ | |
97 | do \ | |
98 | { \ | |
99 | iov[nr].iov_base = str; \ | |
100 | iov[nr].iov_len = len; \ | |
101 | ++nr; \ | |
102 | } \ | |
103 | while (0) | |
104 | ||
105 | /* Generate strings of register contents. */ | |
106 | for (i = 1; i < 4; ++i) | |
107 | { | |
108 | regvalue (&ctx->sc_gr[i], 'R', i, gpregs[i - 1]); | |
109 | if (ctx->sc_nat & (1L << i)) | |
110 | memcpy (gpregs[i - 1] + 7, "NaT ", 16); | |
111 | } | |
112 | for (i = 8; i < 32; ++i) | |
113 | { | |
114 | regvalue (&ctx->sc_gr[i], 'R', i, gpregs[i - 5]); | |
115 | if (ctx->sc_nat & (1L << i)) | |
116 | memcpy (gpregs[i - 1] + 7, "NaT ", 16); | |
117 | } | |
118 | memcpy (gpregs[0] + 1, "GP:", 3); | |
119 | memcpy (gpregs[7] + 1, "SP: ", 4); | |
120 | memcpy (gpregs[8] + 1, "TP: ", 4); | |
121 | ||
122 | regvalue (&ctx->sc_br[0], 'B', 0, bpregs[0]); | |
123 | regvalue (&ctx->sc_br[6], 'B', 6, bpregs[1]); | |
124 | regvalue (&ctx->sc_br[7], 'B', 7, bpregs[2]); | |
125 | memcpy (bpregs[0] + 1, "RP:", 3); | |
126 | ||
127 | if (ctx->sc_flags & IA64_SC_FLAG_FPH_VALID) | |
128 | for (i = 32; i < 128; ++i) | |
129 | regvalue (&ctx->sc_fr[i].u.bits[0], 'F', i, fpregs[i - 32]); | |
130 | ||
131 | hexvalue (ctx->sc_ip, spregs[0], sizeof (spregs[0])); | |
132 | hexvalue (ctx->sc_ar_rsc, spregs[1], sizeof (spregs[1])); | |
133 | hexvalue (ctx->sc_pr, spregs[2], sizeof (spregs[2])); | |
134 | hexvalue (ctx->sc_ar_pfs, spregs[3], sizeof (spregs[3])); | |
135 | hexvalue (ctx->sc_ar_unat, spregs[4], sizeof (spregs[4])); | |
136 | hexvalue (ctx->sc_cfm, spregs[5], sizeof (spregs[5])); | |
137 | hexvalue (ctx->sc_ar_ccv, spregs[6], sizeof (spregs[6])); | |
138 | hexvalue (ctx->sc_ar_fpsr, spregs[7], sizeof (spregs[7])); | |
139 | ||
140 | /* Generate the output. */ | |
141 | ADD_STRING ("Register dump:\n\n"); | |
142 | ||
143 | for (i = 0; i < 32 - 5; ++i) | |
144 | ADD_MEM (gpregs[i], sizeof (gpregs[0]) - 1 + ((i % 3) == 2)); | |
145 | ADD_STRING ("\n"); | |
146 | ||
147 | for (i = 0; i < 3; ++i) | |
148 | ADD_MEM (bpregs[i], sizeof (bpregs[0]) - 1); | |
0347518d | 149 | |
d5efd131 MF |
150 | ADD_STRING ("\n\n IP: "); |
151 | ADD_MEM (spregs[0], sizeof (spregs[0])); | |
152 | ADD_STRING (" RSC: "); | |
153 | ADD_MEM (spregs[1], sizeof (spregs[0])); | |
154 | ADD_STRING (" PR: "); | |
155 | ADD_MEM (spregs[2], sizeof (spregs[0])); | |
156 | ADD_STRING ("\n PFS: "); | |
157 | ADD_MEM (spregs[3], sizeof (spregs[0])); | |
158 | ADD_STRING (" UNAT: "); | |
159 | ADD_MEM (spregs[4], sizeof (spregs[0])); | |
160 | ADD_STRING (" CFM: "); | |
161 | ADD_MEM (spregs[5], sizeof (spregs[0])); | |
162 | ADD_STRING ("\n CCV: "); | |
163 | ADD_MEM (spregs[6], sizeof (spregs[0])); | |
164 | ADD_STRING (" FPSR: "); | |
165 | ADD_MEM (spregs[7], sizeof (spregs[0])); | |
166 | ADD_STRING ("\n"); | |
167 | ||
168 | if (ctx->sc_flags & IA64_SC_FLAG_FPH_VALID) | |
169 | { | |
170 | ADD_STRING ("\n"); | |
171 | ||
172 | for (i = 0; i < 128 - 32; ++i) | |
173 | ADD_MEM (fpregs[i], sizeof (fpregs[0]) - 1 + (i & 1)); | |
174 | } | |
175 | ||
176 | /* Write the stuff out. */ | |
177 | writev (fd, iov, nr); | |
178 | } | |
179 | ||
180 | ||
181 | #define REGISTER_DUMP register_dump (fd, ctx) |