1 /* Dump registers.  64 bit S/390 version.
2    Copyright (C) 2001-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: XXXXXXXXXXXXXXXX  GPR1: XXXXXXXXXXXXXXXX
25  GPR2: XXXXXXXXXXXXXXXX  GPR3: XXXXXXXXXXXXXXXX
26  GPR4: XXXXXXXXXXXXXXXX  GPR5: XXXXXXXXXXXXXXXX
27  GPR6: XXXXXXXXXXXXXXXX  GPR7: XXXXXXXXXXXXXXXX
28  GPR8: XXXXXXXXXXXXXXXX  GPR9: XXXXXXXXXXXXXXXX
29  GPRA: XXXXXXXXXXXXXXXX  GPRB: XXXXXXXXXXXXXXXX
30  GPRC: XXXXXXXXXXXXXXXX  GPRD: XXXXXXXXXXXXXXXX
31  GPRE: XXXXXXXXXXXXXXXX  GPRF: XXXXXXXXXXXXXXXX
32 
33  PSW.MASK: XXXXXXXXXXXXXXXX   PSW.ADDR: XXXXXXXXXXXXXXXX
34 
35  ST(0) XXXX XXXXXXXXXXXXXXXX   ST(1) XXXX XXXXXXXXXXXXXXXX
36  ST(2) XXXX XXXXXXXXXXXXXXXX   ST(3) XXXX XXXXXXXXXXXXXXXX
37  ST(4) XXXX XXXXXXXXXXXXXXXX   ST(5) XXXX XXXXXXXXXXXXXXXX
38  ST(6) XXXX XXXXXXXXXXXXXXXX   ST(7) XXXX XXXXXXXXXXXXXXXX
39  */
40 
41 static void
hexvalue(unsigned long int value,char * buf,size_t len)42 hexvalue (unsigned long int value, char *buf, size_t len)
43 {
44   char *cp = _itoa_word (value, buf + len, 16, 0);
45   while (cp > buf)
46     *--cp = '0';
47 }
48 
49 static void
register_dump(int fd,struct ucontext_t * ctx)50 register_dump (int fd, struct ucontext_t *ctx)
51 {
52   char regs[19][16];
53   struct iovec iov[40];
54   size_t nr = 0;
55 
56 #define ADD_STRING(str) \
57   iov[nr].iov_base = (char *) str;					      \
58   iov[nr].iov_len = strlen (str);					      \
59   ++nr
60 #define ADD_MEM(str, len) \
61   iov[nr].iov_base = str;						      \
62   iov[nr].iov_len = len;						      \
63   ++nr
64 
65   /* Generate strings of register contents.  */
66   hexvalue (ctx->uc_mcontext.gregs[0], regs[0], 16);
67   hexvalue (ctx->uc_mcontext.gregs[1], regs[1], 16);
68   hexvalue (ctx->uc_mcontext.gregs[2], regs[2], 16);
69   hexvalue (ctx->uc_mcontext.gregs[3], regs[3], 16);
70   hexvalue (ctx->uc_mcontext.gregs[4], regs[4], 16);
71   hexvalue (ctx->uc_mcontext.gregs[5], regs[5], 16);
72   hexvalue (ctx->uc_mcontext.gregs[6], regs[6], 16);
73   hexvalue (ctx->uc_mcontext.gregs[7], regs[7], 16);
74   hexvalue (ctx->uc_mcontext.gregs[8], regs[8], 16);
75   hexvalue (ctx->uc_mcontext.gregs[9], regs[9], 16);
76   hexvalue (ctx->uc_mcontext.gregs[10], regs[10], 16);
77   hexvalue (ctx->uc_mcontext.gregs[11], regs[11], 16);
78   hexvalue (ctx->uc_mcontext.gregs[12], regs[12], 16);
79   hexvalue (ctx->uc_mcontext.gregs[13], regs[13], 16);
80   hexvalue (ctx->uc_mcontext.gregs[14], regs[14], 16);
81   hexvalue (ctx->uc_mcontext.gregs[15], regs[15], 16);
82   hexvalue (ctx->uc_mcontext.psw.mask, regs[16], 16);
83   hexvalue (ctx->uc_mcontext.psw.addr, regs[17], 16);
84 
85   /* Generate the output.  */
86   ADD_STRING ("Register dump:\n\n GPR0: ");
87   ADD_MEM (regs[0], 16);
88   ADD_STRING ("  GPR1: ");
89   ADD_MEM (regs[1], 16);
90   ADD_STRING ("  GPR2: ");
91   ADD_MEM (regs[2], 16);
92   ADD_STRING ("  GPR3: ");
93   ADD_MEM (regs[3], 16);
94   ADD_STRING ("\n GPR4: ");
95   ADD_MEM (regs[4], 16);
96   ADD_STRING ("  GPR5: ");
97   ADD_MEM (regs[5], 16);
98   ADD_STRING ("  GPR6: ");
99   ADD_MEM (regs[6], 16);
100   ADD_STRING ("  GPR7: ");
101   ADD_MEM (regs[7], 16);
102   ADD_STRING ("\n GPR8: ");
103   ADD_MEM (regs[8], 16);
104   ADD_STRING ("  GPR9: ");
105   ADD_MEM (regs[9], 16);
106   ADD_STRING ("  GPRA: ");
107   ADD_MEM (regs[10], 16);
108   ADD_STRING ("  GPRB: ");
109   ADD_MEM (regs[11], 16);
110   ADD_STRING ("\n GPRC: ");
111   ADD_MEM (regs[12], 16);
112   ADD_STRING ("  GPRD: ");
113   ADD_MEM (regs[13], 16);
114   ADD_STRING ("  GPRE: ");
115   ADD_MEM (regs[14], 16);
116   ADD_STRING ("  GPRF: ");
117   ADD_MEM (regs[15], 16);
118   ADD_STRING ("\n\n PSW.MASK: ");
119   ADD_MEM (regs[16], 16);
120   ADD_STRING ("  PSW.ADDR: ");
121   ADD_MEM (regs[17], 16);
122   ADD_STRING ("  TRAP: ");
123   ADD_MEM (regs[18], 4);
124   ADD_STRING ("\n");
125 
126   /* Write the stuff out.  */
127   writev (fd, iov, nr);
128 }
129 
130 
131 #define REGISTER_DUMP register_dump (fd, ctx)
132