Back to index

glibc  2.9
register-dump.h
Go to the documentation of this file.
00001 /* Dump registers.
00002    Copyright (C) 1998, 2002, 2004 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Andreas Schwab <schwab@gnu.org>.
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 <stddef.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   D0: XXXXXXXX   D1: XXXXXXXX   D2: XXXXXXXX   D3: XXXXXXXX
00028   D4: XXXXXXXX   D5: XXXXXXXX   D6: XXXXXXXX   D7: XXXXXXXX
00029   A0: XXXXXXXX   A1: XXXXXXXX   A2: XXXXXXXX   A3: XXXXXXXX
00030   A4: XXXXXXXX   A5: XXXXXXXX   A6: XXXXXXXX   A7: XXXXXXXX
00031   PC: XXXXXXXX   SR: XXXX
00032 
00033   OldMask: XXXXXXXX  Vector: XXXX
00034 
00035   FP0: XXXXXXXXXXXXXXXXXXXXXXXX   FP1: XXXXXXXXXXXXXXXXXXXXXXXX
00036   FP2: XXXXXXXXXXXXXXXXXXXXXXXX   FP3: XXXXXXXXXXXXXXXXXXXXXXXX
00037   FP4: XXXXXXXXXXXXXXXXXXXXXXXX   FP5: XXXXXXXXXXXXXXXXXXXXXXXX
00038   FP6: XXXXXXXXXXXXXXXXXXXXXXXX   FP7: XXXXXXXXXXXXXXXXXXXXXXXX
00039   FPCR: XXXXXXXX   FPSR: XXXXXXXX   FPIAR: XXXXXXXX
00040 
00041 */
00042 
00043 #ifndef __mcoldfire__
00044 /* Linux saves only the call-clobbered registers in the sigcontext.  We
00045    need to use a trampoline that saves the rest so that the C code can
00046    access them.  We use the sc_fpstate field, since the handler is not
00047    supposed to return anyway, thus it doesn't matter that it's clobbered.  */
00048 
00049 /* static */ void catch_segfault (int, int, struct sigcontext *);
00050 
00051 /* Dummy function so that we can use asm with arguments.  */
00052 static void __attribute_used__
00053 __dummy__ (void)
00054 {
00055   asm ("\n\
00056 catch_segfault:\n\
00057        move.l 12(%%sp),%%a0\n\
00058        lea %c0(%%a0),%%a0\n\
00059        /* Clear the first 4 bytes to make it a null fp state, just\n\
00060           in case the handler does return.  */\n\
00061        clr.l (%%a0)+\n\
00062        movem.l %%d2-%%d7/%%a2-%%a6,(%%a0)\n\
00063        fmovem.x %%fp2-%%fp7,11*4(%%a0)\n\
00064        jra real_catch_segfault"
00065        : : "n" (offsetof (struct sigcontext, sc_fpstate)));
00066 }
00067 #define catch_segfault(a,b) \
00068   __attribute_used__ real_catch_segfault(a,b)
00069 #endif
00070 
00071 static void
00072 hexvalue (unsigned long int value, char *buf, size_t len)
00073 {
00074   char *cp = _itoa_word (value, buf + len, 16, 0);
00075   while (cp > buf)
00076     *--cp = '0';
00077 }
00078 
00079 static void
00080 register_dump (int fd, struct sigcontext *ctx)
00081 {
00082   char regs[20][8];
00083   char fpregs[11][24];
00084   struct iovec iov[63], *next_iov = iov;
00085   unsigned long *p = (unsigned long *) ctx->sc_fpstate + 1;
00086   unsigned long *pfp = (unsigned long *) ctx->sc_fpregs;
00087   int i, j, fpreg_size;
00088 
00089 #define ADD_STRING(str) \
00090   next_iov->iov_base = (char *) (str); \
00091   next_iov->iov_len = strlen (str); \
00092   ++next_iov
00093 #define ADD_MEM(str, len) \
00094   next_iov->iov_base = (str); \
00095   next_iov->iov_len = (len); \
00096   ++next_iov
00097 
00098 #ifdef __mcoldfire__
00099   fpreg_size = 16;
00100 #else
00101   fpreg_size = 24;
00102 #endif
00103 
00104   /* Generate strings of register contents.  */
00105   hexvalue (ctx->sc_d0, regs[0], 8);
00106   hexvalue (ctx->sc_d1, regs[1], 8);
00107 #ifdef __mcoldfire__
00108   hexvalue (ctx->sc_d2, regs[2], 8);
00109   hexvalue (ctx->sc_d3, regs[3], 8);
00110   hexvalue (ctx->sc_d4, regs[4], 8);
00111   hexvalue (ctx->sc_d5, regs[5], 8);
00112   hexvalue (ctx->sc_d6, regs[6], 8);
00113   hexvalue (ctx->sc_d7, regs[7], 8);
00114 #else
00115   hexvalue (*p++, regs[2], 8);
00116   hexvalue (*p++, regs[3], 8);
00117   hexvalue (*p++, regs[4], 8);
00118   hexvalue (*p++, regs[5], 8);
00119   hexvalue (*p++, regs[6], 8);
00120   hexvalue (*p++, regs[7], 8);
00121 #endif
00122   hexvalue (ctx->sc_a0, regs[8], 8);
00123   hexvalue (ctx->sc_a1, regs[9], 8);
00124 #ifdef __mcoldfire__
00125   hexvalue (ctx->sc_a2, regs[10], 8);
00126   hexvalue (ctx->sc_a3, regs[11], 8);
00127   hexvalue (ctx->sc_a4, regs[12], 8);
00128   hexvalue (ctx->sc_a5, regs[13], 8);
00129   hexvalue (ctx->sc_a6, regs[14], 8);
00130 #else
00131   hexvalue (*p++, regs[10], 8);
00132   hexvalue (*p++, regs[11], 8);
00133   hexvalue (*p++, regs[12], 8);
00134   hexvalue (*p++, regs[13], 8);
00135   hexvalue (*p++, regs[14], 8);
00136 #endif
00137   hexvalue (ctx->sc_usp, regs[15], 8);
00138   hexvalue (ctx->sc_pc, regs[16], 8);
00139   hexvalue (ctx->sc_sr, regs[17], 4);
00140   hexvalue (ctx->sc_mask, regs[18], 8);
00141   hexvalue (ctx->sc_formatvec & 0xfff, regs[19], 4);
00142   for (i = 0; i < 2; i++)
00143     for (j = 0; j < fpreg_size; j += 8)
00144       hexvalue (*pfp++, fpregs[i] + j, 8);
00145 #ifdef __mcoldfire__
00146   p = pfp;
00147 #endif
00148   for (i = 2; i < 8; i++)
00149     for (j = 0; j < fpreg_size; j += 8)
00150       hexvalue (*p++, fpregs[i] + j, 8);
00151   hexvalue (ctx->sc_fpcntl[0], fpregs[8], 8);
00152   hexvalue (ctx->sc_fpcntl[1], fpregs[9], 8);
00153   hexvalue (ctx->sc_fpcntl[2], fpregs[10], 8);
00154 
00155   /* Generate the output.  */
00156   ADD_STRING ("Register dump:\n\n  D0: ");
00157   ADD_MEM (regs[0], 8);
00158   ADD_STRING ("  D1: ");
00159   ADD_MEM (regs[1], 8);
00160   ADD_STRING ("  D2: ");
00161   ADD_MEM (regs[2], 8);
00162   ADD_STRING ("  D3: ");
00163   ADD_MEM (regs[3], 8);
00164   ADD_STRING ("\n  D4: ");
00165   ADD_MEM (regs[4], 8);
00166   ADD_STRING ("  D5: ");
00167   ADD_MEM (regs[5], 8);
00168   ADD_STRING ("  D6: ");
00169   ADD_MEM (regs[6], 8);
00170   ADD_STRING ("  D7: ");
00171   ADD_MEM (regs[7], 8);
00172   ADD_STRING ("\n  A0: ");
00173   ADD_MEM (regs[8], 8);
00174   ADD_STRING ("  A1: ");
00175   ADD_MEM (regs[9], 8);
00176   ADD_STRING ("  A2: ");
00177   ADD_MEM (regs[10], 8);
00178   ADD_STRING ("  A3: ");
00179   ADD_MEM (regs[11], 8);
00180   ADD_STRING ("\n  A4: ");
00181   ADD_MEM (regs[12], 8);
00182   ADD_STRING ("  A5: ");
00183   ADD_MEM (regs[13], 8);
00184   ADD_STRING ("  A6: ");
00185   ADD_MEM (regs[14], 8);
00186   ADD_STRING ("  A7: ");
00187   ADD_MEM (regs[15], 8);
00188   ADD_STRING ("\n  PC: ");
00189   ADD_MEM (regs[16], 8);
00190   ADD_STRING ("  SR: ");
00191   ADD_MEM (regs[17], 4);
00192 
00193   ADD_STRING ("\n\n  OldMask: ");
00194   ADD_MEM (regs[18], 8);
00195   ADD_STRING ("  Vector: ");
00196   ADD_MEM (regs[19], 4);
00197 
00198   ADD_STRING ("\n\n  FP0: ");
00199   ADD_MEM (fpregs[0], fpreg_size);
00200   ADD_STRING ("  FP1: ");
00201   ADD_MEM (fpregs[1], fpreg_size);
00202   ADD_STRING ("\n  FP2: ");
00203   ADD_MEM (fpregs[2], fpreg_size);
00204   ADD_STRING ("  FP3: ");
00205   ADD_MEM (fpregs[3], fpreg_size);
00206   ADD_STRING ("\n  FP4: ");
00207   ADD_MEM (fpregs[4], fpreg_size);
00208   ADD_STRING ("  FP5: ");
00209   ADD_MEM (fpregs[5], fpreg_size);
00210   ADD_STRING ("\n  FP6: ");
00211   ADD_MEM (fpregs[6], fpreg_size);
00212   ADD_STRING ("  FP7: ");
00213   ADD_MEM (fpregs[7], fpreg_size);
00214   ADD_STRING ("\n  FPCR: ");
00215   ADD_MEM (fpregs[8], 8);
00216   ADD_STRING ("  FPSR: ");
00217   ADD_MEM (fpregs[9], 8);
00218   ADD_STRING ("  FPIAR: ");
00219   ADD_MEM (fpregs[10], 8);
00220   ADD_STRING ("\n");
00221 
00222   /* Write the stuff out.  */
00223   writev (fd, iov, next_iov - iov);
00224 }
00225 
00226 #define REGISTER_DUMP register_dump (fd, ctx)