Add Changelog ...
[jlayton/glibc.git] / ports / sysdeps / unix / sysv / linux / ia64 / register-dump.h
1 /* Dump registers.
2    Copyright (C) 2004-2012 Free Software Foundation, Inc.
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
17    License along with the GNU C Library; if not, see
18    <http://www.gnu.org/licenses/>.  */
19
20 #include <string.h>
21 #include <sys/uio.h>
22 #include <_itoa.h>
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);
149
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)