Back to index

glibc  2.9
register-dump.h
Go to the documentation of this file.
00001 /* Dump registers.
00002    Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <sys/uio.h>
00021 #include <stdio-common/_itoa.h>
00022 
00023 /* We will print the register dump in this format:
00024 
00025  RAX: XXXXXXXXXXXXXXXX   RBX: XXXXXXXXXXXXXXXX  RCX: XXXXXXXXXXXXXXXX
00026  RDX: XXXXXXXXXXXXXXXX   RSI: XXXXXXXXXXXXXXXX  RDI: XXXXXXXXXXXXXXXX
00027  RBP: XXXXXXXXXXXXXXXX   R8 : XXXXXXXXXXXXXXXX  R9 : XXXXXXXXXXXXXXXX
00028  R10: XXXXXXXXXXXXXXXX   R11: XXXXXXXXXXXXXXXX  R12: XXXXXXXXXXXXXXXX
00029  R13: XXXXXXXXXXXXXXXX   R14: XXXXXXXXXXXXXXXX  R15: XXXXXXXXXXXXXXXX
00030  RSP: XXXXXXXXXXXXXXXX
00031 
00032  RIP: XXXXXXXXXXXXXXXX   EFLAGS: XXXXXXXX
00033 
00034  CS:  XXXX   DS: XXXX   ES: XXXX   FS: XXXX   GS: XXXX
00035 
00036  Trap:  XXXXXXXX   Error: XXXXXXXX   OldMask: XXXXXXXX
00037  RSP/SIGNAL: XXXXXXXXXXXXXXXX  CR2: XXXXXXXX
00038 
00039  FPUCW: XXXXXXXX   FPUSW: XXXXXXXX   TAG: XXXXXXXX
00040  IPOFF: XXXXXXXX   CSSEL: XXXX   DATAOFF: XXXXXXXX   DATASEL: XXXX
00041 
00042  ST(0) XXXX XXXXXXXXXXXXXXXX   ST(1) XXXX XXXXXXXXXXXXXXXX
00043  ST(2) XXXX XXXXXXXXXXXXXXXX   ST(3) XXXX XXXXXXXXXXXXXXXX
00044  ST(4) XXXX XXXXXXXXXXXXXXXX   ST(5) XXXX XXXXXXXXXXXXXXXX
00045  ST(6) XXXX XXXXXXXXXXXXXXXX   ST(7) XXXX XXXXXXXXXXXXXXXX
00046 
00047  mxcsr: XXXX
00048  XMM0 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM1 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00049  XMM2 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM3 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00050  XMM4 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM5 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00051  XMM6 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM7 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00052  XMM8 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM9 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00053  XMM10: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM11: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00054  XMM12: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM13: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00055  XMM14: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM15: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00056 
00057  */
00058 
00059 static void
00060 hexvalue (unsigned long int value, char *buf, size_t len)
00061 {
00062   char *cp = _itoa_word (value, buf + len, 16, 0);
00063   while (cp > buf)
00064     *--cp = '0';
00065 }
00066 
00067 static void
00068 register_dump (int fd, struct ucontext *ctx)
00069 {
00070   char regs[25][16];
00071   char fpregs[30][8];
00072   char xmmregs[16][32];
00073   struct iovec iov[147];
00074   size_t nr = 0;
00075   int i;
00076 
00077 #define ADD_STRING(str) \
00078   iov[nr].iov_base = (char *) str;                                   \
00079   iov[nr].iov_len = strlen (str);                                    \
00080   ++nr
00081 #define ADD_MEM(str, len) \
00082   iov[nr].iov_base = str;                                            \
00083   iov[nr].iov_len = len;                                             \
00084   ++nr
00085 
00086   /* Generate strings of register contents.  */
00087   hexvalue (ctx->uc_mcontext.gregs[REG_RAX], regs[0], 16);
00088   hexvalue (ctx->uc_mcontext.gregs[REG_RBX], regs[1], 16);
00089   hexvalue (ctx->uc_mcontext.gregs[REG_RCX], regs[2], 16);
00090   hexvalue (ctx->uc_mcontext.gregs[REG_RDX], regs[3], 16);
00091   hexvalue (ctx->uc_mcontext.gregs[REG_RSI], regs[4], 16);
00092   hexvalue (ctx->uc_mcontext.gregs[REG_RDI], regs[5], 16);
00093   hexvalue (ctx->uc_mcontext.gregs[REG_RBP], regs[6], 16);
00094   hexvalue (ctx->uc_mcontext.gregs[REG_R8], regs[7], 16);
00095   hexvalue (ctx->uc_mcontext.gregs[REG_R9], regs[8], 16);
00096   hexvalue (ctx->uc_mcontext.gregs[REG_R10], regs[9], 16);
00097   hexvalue (ctx->uc_mcontext.gregs[REG_R11], regs[10], 16);
00098   hexvalue (ctx->uc_mcontext.gregs[REG_R12], regs[11], 16);
00099   hexvalue (ctx->uc_mcontext.gregs[REG_R13], regs[12], 16);
00100   hexvalue (ctx->uc_mcontext.gregs[REG_R14], regs[13], 16);
00101   hexvalue (ctx->uc_mcontext.gregs[REG_R15], regs[14], 16);
00102   hexvalue (ctx->uc_mcontext.gregs[REG_RSP], regs[15], 16);
00103   hexvalue (ctx->uc_mcontext.gregs[REG_RIP], regs[16], 16);
00104 
00105   hexvalue (ctx->uc_mcontext.gregs[REG_EFL], regs[17], 8);
00106   hexvalue (ctx->uc_mcontext.gregs[REG_CSGSFS] & 0xffff, regs[18], 4);
00107   hexvalue ((ctx->uc_mcontext.gregs[REG_CSGSFS] >> 16) & 0xffff, regs[19], 4);
00108   hexvalue ((ctx->uc_mcontext.gregs[REG_CSGSFS] >> 32) & 0xffff, regs[20], 4);
00109   /* hexvalue (ctx->ss, regs[23], 4); */
00110   hexvalue (ctx->uc_mcontext.gregs[REG_TRAPNO], regs[21], 8);
00111   hexvalue (ctx->uc_mcontext.gregs[REG_ERR], regs[22], 8);
00112   hexvalue (ctx->uc_mcontext.gregs[REG_OLDMASK], regs[23], 8);
00113   hexvalue (ctx->uc_mcontext.gregs[REG_CR2], regs[24], 8);
00114 
00115   /* Generate the output.  */
00116   ADD_STRING ("Register dump:\n\n RAX: ");
00117   ADD_MEM (regs[0], 16);
00118   ADD_STRING ("   RBX: ");
00119   ADD_MEM (regs[1], 16);
00120   ADD_STRING ("   RCX: ");
00121   ADD_MEM (regs[2], 16);
00122   ADD_STRING ("\n RDX: ");
00123   ADD_MEM (regs[3], 16);
00124   ADD_STRING ("   RSI: ");
00125   ADD_MEM (regs[4], 16);
00126   ADD_STRING ("   RDI: ");
00127   ADD_MEM (regs[5], 16);
00128   ADD_STRING ("\n RBP: ");
00129   ADD_MEM (regs[6], 16);
00130   ADD_STRING ("   R8 : ");
00131   ADD_MEM (regs[7], 16);
00132   ADD_STRING ("   R9 : ");
00133   ADD_MEM (regs[8], 16);
00134   ADD_STRING ("\n R10: ");
00135   ADD_MEM (regs[9], 16);
00136   ADD_STRING ("   R11: ");
00137   ADD_MEM (regs[10], 16);
00138   ADD_STRING ("   R12: ");
00139   ADD_MEM (regs[11], 16);
00140   ADD_STRING ("\n R13: ");
00141   ADD_MEM (regs[12], 16);
00142   ADD_STRING ("   R14: ");
00143   ADD_MEM (regs[13], 16);
00144   ADD_STRING ("   R15: ");
00145   ADD_MEM (regs[14], 16);
00146   ADD_STRING ("\n RSP: ");
00147   ADD_MEM (regs[15], 16);
00148   ADD_STRING ("\n\n RIP: ");
00149   ADD_MEM (regs[16], 16);
00150   ADD_STRING ("   EFLAGS: ");
00151   ADD_MEM (regs[17], 8);
00152   ADD_STRING ("\n\n CS: ");
00153   ADD_MEM (regs[18], 4);
00154   ADD_STRING ("   FS: ");
00155   ADD_MEM (regs[19], 4);
00156   ADD_STRING ("   GS: ");
00157   ADD_MEM (regs[20], 4);
00158   /*
00159   ADD_STRING ("   SS: ");
00160   ADD_MEM (regs[23], 4);
00161   */
00162   ADD_STRING ("\n\n Trap: ");
00163   ADD_MEM (regs[21], 8);
00164   ADD_STRING ("   Error: ");
00165   ADD_MEM (regs[22], 8);
00166   ADD_STRING ("   OldMask: ");
00167   ADD_MEM (regs[23], 8);
00168   ADD_STRING ("   CR2: ");
00169   ADD_MEM (regs[24], 8);
00170 
00171   if (ctx->uc_mcontext.fpregs != NULL)
00172     {
00173 
00174       /* Generate output for the FPU control/status registers.  */
00175       hexvalue (ctx->uc_mcontext.fpregs->cwd, fpregs[0], 8);
00176       hexvalue (ctx->uc_mcontext.fpregs->swd, fpregs[1], 8);
00177       hexvalue (ctx->uc_mcontext.fpregs->ftw, fpregs[2], 8);
00178       hexvalue (ctx->uc_mcontext.fpregs->rip, fpregs[3], 8);
00179       hexvalue (ctx->uc_mcontext.fpregs->rdp, fpregs[4], 8);
00180 
00181       ADD_STRING ("\n\n FPUCW: ");
00182       ADD_MEM (fpregs[0], 8);
00183       ADD_STRING ("   FPUSW: ");
00184       ADD_MEM (fpregs[1], 8);
00185       ADD_STRING ("   TAG: ");
00186       ADD_MEM (fpregs[2], 8);
00187       ADD_STRING ("\n RIP: ");
00188       ADD_MEM (fpregs[3], 8);
00189       ADD_STRING ("   RDP: ");
00190       ADD_MEM (fpregs[4], 8);
00191 
00192       /* Now the real FPU registers.  */
00193       hexvalue (ctx->uc_mcontext.fpregs->_st[0].exponent, fpregs[5], 8);
00194       hexvalue (ctx->uc_mcontext.fpregs->_st[0].significand[3] << 16
00195               | ctx->uc_mcontext.fpregs->_st[0].significand[2], fpregs[6],
00196               8);
00197       hexvalue (ctx->uc_mcontext.fpregs->_st[0].significand[1] << 16
00198               | ctx->uc_mcontext.fpregs->_st[0].significand[0], fpregs[7],
00199               8);
00200       hexvalue (ctx->uc_mcontext.fpregs->_st[1].exponent, fpregs[8], 8);
00201       hexvalue (ctx->uc_mcontext.fpregs->_st[1].significand[3] << 16
00202               | ctx->uc_mcontext.fpregs->_st[1].significand[2], fpregs[9],
00203               8);
00204       hexvalue (ctx->uc_mcontext.fpregs->_st[1].significand[1] << 16
00205               | ctx->uc_mcontext.fpregs->_st[1].significand[0], fpregs[10],
00206               8);
00207       hexvalue (ctx->uc_mcontext.fpregs->_st[2].exponent, fpregs[11], 8);
00208       hexvalue (ctx->uc_mcontext.fpregs->_st[2].significand[3] << 16
00209               | ctx->uc_mcontext.fpregs->_st[2].significand[2], fpregs[12],
00210               8);
00211       hexvalue (ctx->uc_mcontext.fpregs->_st[2].significand[1] << 16
00212               | ctx->uc_mcontext.fpregs->_st[2].significand[0], fpregs[13],
00213               8);
00214       hexvalue (ctx->uc_mcontext.fpregs->_st[3].exponent, fpregs[14], 8);
00215       hexvalue (ctx->uc_mcontext.fpregs->_st[3].significand[3] << 16
00216               | ctx->uc_mcontext.fpregs->_st[3].significand[2], fpregs[15],
00217               8);
00218       hexvalue (ctx->uc_mcontext.fpregs->_st[3].significand[1] << 16
00219               | ctx->uc_mcontext.fpregs->_st[3].significand[0], fpregs[16],
00220               8);
00221       hexvalue (ctx->uc_mcontext.fpregs->_st[4].exponent, fpregs[17], 8);
00222       hexvalue (ctx->uc_mcontext.fpregs->_st[4].significand[3] << 16
00223               | ctx->uc_mcontext.fpregs->_st[4].significand[2], fpregs[18],
00224               8);
00225       hexvalue (ctx->uc_mcontext.fpregs->_st[4].significand[1] << 16
00226               | ctx->uc_mcontext.fpregs->_st[4].significand[0], fpregs[19],
00227               8);
00228       hexvalue (ctx->uc_mcontext.fpregs->_st[5].exponent, fpregs[20], 8);
00229       hexvalue (ctx->uc_mcontext.fpregs->_st[5].significand[3] << 16
00230               | ctx->uc_mcontext.fpregs->_st[5].significand[2], fpregs[21],
00231               8);
00232       hexvalue (ctx->uc_mcontext.fpregs->_st[5].significand[1] << 16
00233               | ctx->uc_mcontext.fpregs->_st[5].significand[0], fpregs[22],
00234               8);
00235       hexvalue (ctx->uc_mcontext.fpregs->_st[6].exponent, fpregs[23], 8);
00236       hexvalue (ctx->uc_mcontext.fpregs->_st[6].significand[3] << 16
00237               | ctx->uc_mcontext.fpregs->_st[6].significand[2], fpregs[24],
00238               8);
00239       hexvalue (ctx->uc_mcontext.fpregs->_st[6].significand[1] << 16
00240               | ctx->uc_mcontext.fpregs->_st[6].significand[0], fpregs[25],
00241               8);
00242       hexvalue (ctx->uc_mcontext.fpregs->_st[7].exponent, fpregs[26], 8);
00243       hexvalue (ctx->uc_mcontext.fpregs->_st[7].significand[3] << 16
00244               | ctx->uc_mcontext.fpregs->_st[7].significand[2], fpregs[27],
00245               8);
00246       hexvalue (ctx->uc_mcontext.fpregs->_st[7].significand[1] << 16
00247               | ctx->uc_mcontext.fpregs->_st[7].significand[0], fpregs[28],
00248               8);
00249 
00250       hexvalue (ctx->uc_mcontext.fpregs->mxcsr, fpregs[29], 4);
00251 
00252       for (i = 0; i < 16; i++)
00253        hexvalue (ctx->uc_mcontext.fpregs->_xmm[i].element[3] << 24
00254                 | ctx->uc_mcontext.fpregs->_xmm[i].element[2] << 16
00255                 | ctx->uc_mcontext.fpregs->_xmm[i].element[1] << 8
00256                 | ctx->uc_mcontext.fpregs->_xmm[i].element[0], xmmregs[i],
00257                 32);
00258 
00259 
00260       ADD_STRING ("\n\n ST(0) ");
00261       ADD_MEM (fpregs[5], 4);
00262       ADD_STRING (" ");
00263       ADD_MEM (fpregs[6], 8);
00264       ADD_MEM (fpregs[7], 8);
00265       ADD_STRING ("   ST(1) ");
00266       ADD_MEM (fpregs[8], 4);
00267       ADD_STRING (" ");
00268       ADD_MEM (fpregs[9], 8);
00269       ADD_MEM (fpregs[10], 8);
00270       ADD_STRING ("\n ST(2) ");
00271       ADD_MEM (fpregs[11], 4);
00272       ADD_STRING (" ");
00273       ADD_MEM (fpregs[12], 8);
00274       ADD_MEM (fpregs[13], 8);
00275       ADD_STRING ("   ST(3) ");
00276       ADD_MEM (fpregs[14], 4);
00277       ADD_STRING (" ");
00278       ADD_MEM (fpregs[15], 8);
00279       ADD_MEM (fpregs[16], 8);
00280       ADD_STRING ("\n ST(4) ");
00281       ADD_MEM (fpregs[17], 4);
00282       ADD_STRING (" ");
00283       ADD_MEM (fpregs[18], 8);
00284       ADD_MEM (fpregs[19], 8);
00285       ADD_STRING ("   ST(5) ");
00286       ADD_MEM (fpregs[20], 4);
00287       ADD_STRING (" ");
00288       ADD_MEM (fpregs[21], 8);
00289       ADD_MEM (fpregs[22], 8);
00290       ADD_STRING ("\n ST(6) ");
00291       ADD_MEM (fpregs[23], 4);
00292       ADD_STRING (" ");
00293       ADD_MEM (fpregs[24], 8);
00294       ADD_MEM (fpregs[25], 8);
00295       ADD_STRING ("   ST(7) ");
00296       ADD_MEM (fpregs[27], 4);
00297       ADD_STRING (" ");
00298       ADD_MEM (fpregs[27], 8);
00299       ADD_MEM (fpregs[28], 8);
00300 
00301       ADD_STRING ("\n mxcsr: ");
00302       ADD_MEM (fpregs[29], 4);
00303 
00304       ADD_STRING ("\n XMM0:  ");
00305       ADD_MEM (xmmregs[0], 32);
00306       ADD_STRING (" XMM1:  ");
00307       ADD_MEM (xmmregs[0], 32);
00308       ADD_STRING ("\n XMM2:  ");
00309       ADD_MEM (xmmregs[0], 32);
00310       ADD_STRING (" XMM3:  ");
00311       ADD_MEM (xmmregs[0], 32);
00312       ADD_STRING ("\n XMM4:  ");
00313       ADD_MEM (xmmregs[0], 32);
00314       ADD_STRING (" XMM5:  ");
00315       ADD_MEM (xmmregs[0], 32);
00316       ADD_STRING ("\n XMM6:  ");
00317       ADD_MEM (xmmregs[0], 32);
00318       ADD_STRING (" XMM7:  ");
00319       ADD_MEM (xmmregs[0], 32);
00320       ADD_STRING ("\n XMM8:  ");
00321       ADD_MEM (xmmregs[0], 32);
00322       ADD_STRING (" XMM9:  ");
00323       ADD_MEM (xmmregs[0], 32);
00324       ADD_STRING ("\n XMM10: ");
00325       ADD_MEM (xmmregs[0], 32);
00326       ADD_STRING (" XMM11: ");
00327       ADD_MEM (xmmregs[0], 32);
00328       ADD_STRING ("\n XMM12: ");
00329       ADD_MEM (xmmregs[0], 32);
00330       ADD_STRING (" XMM13: ");
00331       ADD_MEM (xmmregs[0], 32);
00332       ADD_STRING ("\n XMM14: ");
00333       ADD_MEM (xmmregs[0], 32);
00334       ADD_STRING (" XMM15: ");
00335       ADD_MEM (xmmregs[0], 32);
00336 
00337     }
00338 
00339   ADD_STRING ("\n");
00340 
00341   /* Write the stuff out.  */
00342   writev (fd, iov, nr);
00343 }
00344 
00345 
00346 #define REGISTER_DUMP register_dump (fd, ctx)