Back to index

glibc  2.9
register-dump.h
Go to the documentation of this file.
00001 /* Dump registers.
00002    Copyright (C) 2004 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include <string.h>
00022 #include <sys/uio.h>
00023 #include <stdio-common/_itoa.h>
00024 
00025 /* We will print the register dump in this format:
00026 
00027  GP:   XXXXXXXXXXXXXXXX R2:   XXXXXXXXXXXXXXXX R3:   XXXXXXXXXXXXXXXX
00028  R8:   XXXXXXXXXXXXXXXX R9:   XXXXXXXXXXXXXXXX R10:  XXXXXXXXXXXXXXXX
00029  R11:  XXXXXXXXXXXXXXXX SP:   XXXXXXXXXXXXXXXX TP:   XXXXXXXXXXXXXXXX
00030  R14:  XXXXXXXXXXXXXXXX R15:  XXXXXXXXXXXXXXXX R16:  XXXXXXXXXXXXXXXX
00031  R17:  XXXXXXXXXXXXXXXX R18:  XXXXXXXXXXXXXXXX R19:  XXXXXXXXXXXXXXXX
00032  R20:  XXXXXXXXXXXXXXXX R21:  XXXXXXXXXXXXXXXX R22:  XXXXXXXXXXXXXXXX
00033  R23:  XXXXXXXXXXXXXXXX R24:  XXXXXXXXXXXXXXXX R25:  XXXXXXXXXXXXXXXX
00034  R26:  XXXXXXXXXXXXXXXX R27:  XXXXXXXXXXXXXXXX R28:  XXXXXXXXXXXXXXXX
00035  R29:  XXXXXXXXXXXXXXXX R30:  XXXXXXXXXXXXXXXX R31:  XXXXXXXXXXXXXXXX
00036 
00037  RP:   XXXXXXXXXXXXXXXX B6:   XXXXXXXXXXXXXXXX B7:   XXXXXXXXXXXXXXXX
00038 
00039  IP:   XXXXXXXXXXXXXXXX RSC:  XXXXXXXXXXXXXXXX PR:   XXXXXXXXXXXXXXXX
00040  PFS:  XXXXXXXXXXXXXXXX UNAT: XXXXXXXXXXXXXXXX CFM:  XXXXXXXXXXXXXXXX
00041  CCV:  XXXXXXXXXXXXXXXX FPSR: XXXXXXXXXXXXXXXX
00042 
00043  F32:  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX F33:  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00044  F34:  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX F35:  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00045 ...
00046  F124: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX F125: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00047  F126: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX F127: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00048  */
00049 
00050 static void
00051 hexvalue (unsigned long int value, char *buf, size_t len)
00052 {
00053   char *cp = _itoa_word (value, buf + len, 16, 0);
00054   while (cp > buf)
00055     *--cp = '0';
00056 }
00057 
00058 static void
00059 regvalue (unsigned long int *value, char letter, int regno, char *buf)
00060 {
00061   int n = regno >= 100 ? 3 : regno >= 10 ? 2 : 1;
00062   buf[0] = ' ';
00063   buf[1] = letter;
00064   _itoa_word (regno, buf + 2 + n, 10, 0);
00065   buf[2 + n] = ':';
00066   for (++n; n <= 4; ++n)
00067     buf[2 + n] = ' ';
00068   hexvalue (value[0], buf + 7, 16);
00069   if (letter == 'F')
00070     {
00071       hexvalue (value[1], buf + 7 + 16, 16);
00072       buf[7 + 32] = '\n';
00073     }
00074   else
00075     buf[7 + 16] = '\n';
00076 }
00077 
00078 static void
00079 register_dump (int fd, struct sigcontext *ctx)
00080 {
00081   char gpregs[32 - 5][8 + 16];
00082   char fpregs[128 - 32][8 + 32];
00083   char bpregs[3][8 + 16];
00084   char spregs[8][16];
00085   struct iovec iov[146];
00086   size_t nr = 0;
00087   int i;
00088 
00089 #define ADD_STRING(str) \
00090   do                                                                 \
00091     {                                                                \
00092       iov[nr].iov_base = (char *) str;                                      \
00093       iov[nr].iov_len = strlen (str);                                       \
00094       ++nr;                                                          \
00095     }                                                                \
00096   while (0)
00097 #define ADD_MEM(str, len) \
00098   do                                                                 \
00099     {                                                                \
00100       iov[nr].iov_base = str;                                               \
00101       iov[nr].iov_len = len;                                                \
00102       ++nr;                                                          \
00103     }                                                                \
00104   while (0)
00105 
00106   /* Generate strings of register contents.  */
00107   for (i = 1; i < 4; ++i)
00108     {
00109       regvalue (&ctx->sc_gr[i], 'R', i, gpregs[i - 1]);
00110       if (ctx->sc_nat & (1L << i))
00111         memcpy (gpregs[i - 1] + 7, "NaT             ", 16);
00112     }
00113   for (i = 8; i < 32; ++i)
00114     {
00115       regvalue (&ctx->sc_gr[i], 'R', i, gpregs[i - 5]);
00116       if (ctx->sc_nat & (1L << i))
00117         memcpy (gpregs[i - 1] + 7, "NaT             ", 16);
00118     }
00119   memcpy (gpregs[0] + 1, "GP:", 3);
00120   memcpy (gpregs[7] + 1, "SP: ", 4);
00121   memcpy (gpregs[8] + 1, "TP: ", 4);
00122 
00123   regvalue (&ctx->sc_br[0], 'B', 0, bpregs[0]);
00124   regvalue (&ctx->sc_br[6], 'B', 6, bpregs[1]);
00125   regvalue (&ctx->sc_br[7], 'B', 7, bpregs[2]);
00126   memcpy (bpregs[0] + 1, "RP:", 3);
00127 
00128   if (ctx->sc_flags & IA64_SC_FLAG_FPH_VALID)
00129     for (i = 32; i < 128; ++i)
00130       regvalue (&ctx->sc_fr[i].u.bits[0], 'F', i, fpregs[i - 32]);
00131 
00132   hexvalue (ctx->sc_ip, spregs[0], sizeof (spregs[0]));
00133   hexvalue (ctx->sc_ar_rsc, spregs[1], sizeof (spregs[1]));
00134   hexvalue (ctx->sc_pr, spregs[2], sizeof (spregs[2]));
00135   hexvalue (ctx->sc_ar_pfs, spregs[3], sizeof (spregs[3]));
00136   hexvalue (ctx->sc_ar_unat, spregs[4], sizeof (spregs[4]));
00137   hexvalue (ctx->sc_cfm, spregs[5], sizeof (spregs[5]));
00138   hexvalue (ctx->sc_ar_ccv, spregs[6], sizeof (spregs[6]));
00139   hexvalue (ctx->sc_ar_fpsr, spregs[7], sizeof (spregs[7]));
00140 
00141   /* Generate the output.  */
00142   ADD_STRING ("Register dump:\n\n");
00143 
00144   for (i = 0; i < 32 - 5; ++i)
00145     ADD_MEM (gpregs[i], sizeof (gpregs[0]) - 1 + ((i % 3) == 2));
00146   ADD_STRING ("\n");
00147 
00148   for (i = 0; i < 3; ++i)
00149     ADD_MEM (bpregs[i], sizeof (bpregs[0]) - 1);
00150     
00151   ADD_STRING ("\n\n IP:   ");
00152   ADD_MEM (spregs[0], sizeof (spregs[0]));
00153   ADD_STRING (" RSC:  ");
00154   ADD_MEM (spregs[1], sizeof (spregs[0]));
00155   ADD_STRING (" PR:   ");
00156   ADD_MEM (spregs[2], sizeof (spregs[0]));
00157   ADD_STRING ("\n PFS:  ");
00158   ADD_MEM (spregs[3], sizeof (spregs[0]));
00159   ADD_STRING (" UNAT: ");
00160   ADD_MEM (spregs[4], sizeof (spregs[0]));
00161   ADD_STRING (" CFM:  ");
00162   ADD_MEM (spregs[5], sizeof (spregs[0]));
00163   ADD_STRING ("\n CCV:  ");
00164   ADD_MEM (spregs[6], sizeof (spregs[0]));
00165   ADD_STRING (" FPSR: ");
00166   ADD_MEM (spregs[7], sizeof (spregs[0]));
00167   ADD_STRING ("\n");
00168 
00169   if (ctx->sc_flags & IA64_SC_FLAG_FPH_VALID)
00170     {
00171       ADD_STRING ("\n");
00172 
00173       for (i = 0; i < 128 - 32; ++i)
00174         ADD_MEM (fpregs[i], sizeof (fpregs[0]) - 1 + (i & 1));
00175     }
00176 
00177   /* Write the stuff out.  */
00178   writev (fd, iov, nr);
00179 }
00180 
00181 
00182 #define REGISTER_DUMP register_dump (fd, ctx)