1 /* Dump registers.
2    Copyright (C) 2000-2021 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <sys/uio.h>
20 #include <_itoa.h>
21 
22 /* We will print the register dump in this format:
23 
24  GPR0: XXXXXXXX  GPR1: XXXXXXXX  GPR2: XXXXXXXX  GPR3: XXXXXXXX
25  GPR4: XXXXXXXX  GPR5: XXXXXXXX  GPR6: XXXXXXXX  GPR7: XXXXXXXX
26  GPR8: XXXXXXXX  GPR9: XXXXXXXX  GPRA: XXXXXXXX  GPRB: XXXXXXXX
27  GPRC: XXXXXXXX  GPRD: XXXXXXXX  GPRE: XXXXXXXX  GPRF: XXXXXXXX
28 
29  PSW.MASK: XXXXXXXX   PSW.ADDR: XXXXXXXX
30 
31  ST(0) XXXX XXXXXXXXXXXXXXXX   ST(1) XXXX XXXXXXXXXXXXXXXX
32  ST(2) XXXX XXXXXXXXXXXXXXXX   ST(3) XXXX XXXXXXXXXXXXXXXX
33  ST(4) XXXX XXXXXXXXXXXXXXXX   ST(5) XXXX XXXXXXXXXXXXXXXX
34  ST(6) XXXX XXXXXXXXXXXXXXXX   ST(7) XXXX XXXXXXXXXXXXXXXX
35 
36  */
37 
38 static void
hexvalue(unsigned long int value,char * buf,size_t len)39 hexvalue (unsigned long int value, char *buf, size_t len)
40 {
41   char *cp = _itoa_word (value, buf + len, 16, 0);
42   while (cp > buf)
43     *--cp = '0';
44 }
45 
46 static void
register_dump(int fd,struct ucontext_t * ctx)47 register_dump (int fd, struct ucontext_t *ctx)
48 {
49   char regs[19][8];
50   struct iovec iov[40];
51   size_t nr = 0;
52 
53 #define ADD_STRING(str) \
54   iov[nr].iov_base = (char *) str;					      \
55   iov[nr].iov_len = strlen (str);					      \
56   ++nr
57 #define ADD_MEM(str, len) \
58   iov[nr].iov_base = str;						      \
59   iov[nr].iov_len = len;						      \
60   ++nr
61 
62   /* Generate strings of register contents.  */
63   hexvalue (ctx->uc_mcontext.gregs[0], regs[0], 8);
64   hexvalue (ctx->uc_mcontext.gregs[1], regs[1], 8);
65   hexvalue (ctx->uc_mcontext.gregs[2], regs[2], 8);
66   hexvalue (ctx->uc_mcontext.gregs[3], regs[3], 8);
67   hexvalue (ctx->uc_mcontext.gregs[4], regs[4], 8);
68   hexvalue (ctx->uc_mcontext.gregs[5], regs[5], 8);
69   hexvalue (ctx->uc_mcontext.gregs[6], regs[6], 8);
70   hexvalue (ctx->uc_mcontext.gregs[7], regs[7], 8);
71   hexvalue (ctx->uc_mcontext.gregs[8], regs[8], 8);
72   hexvalue (ctx->uc_mcontext.gregs[9], regs[9], 8);
73   hexvalue (ctx->uc_mcontext.gregs[10], regs[10], 8);
74   hexvalue (ctx->uc_mcontext.gregs[11], regs[11], 8);
75   hexvalue (ctx->uc_mcontext.gregs[12], regs[12], 8);
76   hexvalue (ctx->uc_mcontext.gregs[13], regs[13], 8);
77   hexvalue (ctx->uc_mcontext.gregs[14], regs[14], 8);
78   hexvalue (ctx->uc_mcontext.gregs[15], regs[15], 8);
79   hexvalue (ctx->uc_mcontext.psw.mask, regs[16], 8);
80   hexvalue (ctx->uc_mcontext.psw.addr, regs[17], 8);
81 
82   /* Generate the output.  */
83   ADD_STRING ("Register dump:\n\n GPR0: ");
84   ADD_MEM (regs[0], 8);
85   ADD_STRING ("  GPR1: ");
86   ADD_MEM (regs[1], 8);
87   ADD_STRING ("  GPR2: ");
88   ADD_MEM (regs[2], 8);
89   ADD_STRING ("  GPR3: ");
90   ADD_MEM (regs[3], 8);
91   ADD_STRING ("\n GPR4: ");
92   ADD_MEM (regs[4], 8);
93   ADD_STRING ("  GPR5: ");
94   ADD_MEM (regs[5], 8);
95   ADD_STRING ("  GPR6: ");
96   ADD_MEM (regs[6], 8);
97   ADD_STRING ("  GPR7: ");
98   ADD_MEM (regs[7], 8);
99   ADD_STRING ("\n GPR8: ");
100   ADD_MEM (regs[8], 8);
101   ADD_STRING ("  GPR9: ");
102   ADD_MEM (regs[9], 8);
103   ADD_STRING ("  GPRA: ");
104   ADD_MEM (regs[10], 8);
105   ADD_STRING ("  GPRB: ");
106   ADD_MEM (regs[11], 8);
107   ADD_STRING ("\n GPRC: ");
108   ADD_MEM (regs[12], 8);
109   ADD_STRING ("  GPRD: ");
110   ADD_MEM (regs[13], 8);
111   ADD_STRING ("  GPRE: ");
112   ADD_MEM (regs[14], 8);
113   ADD_STRING ("  GPRF: ");
114   ADD_MEM (regs[15], 8);
115   ADD_STRING ("\n\n PSW.MASK: ");
116   ADD_MEM (regs[16], 8);
117   ADD_STRING ("  PSW.ADDR: ");
118   ADD_MEM (regs[17], 8);
119   ADD_STRING ("  TRAP: ");
120   ADD_MEM (regs[18], 4);
121   ADD_STRING ("\n");
122 
123   /* Write the stuff out.  */
124   writev (fd, iov, nr);
125 }
126 
127 
128 #define REGISTER_DUMP register_dump (fd, ctx)
129