1 /*
2 * Copyright (c) 2021 The strace developers.
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: LGPL-2.1-or-later
6 */
7
8 #ifdef MPERS_IS_m32
9 # define TRACEE_KLONGSIZE 4
10 #else
11 # define TRACEE_KLONGSIZE SIZEOF_KERNEL_LONG_T
12 #endif
13
14 static void
15 arch_decode_prstatus_regset(struct tcb *const tcp,
16 const kernel_ulong_t addr,
17 const kernel_ulong_t size)
18 {
19 struct_prstatus_regset regs;
20 const size_t fetch_size = MIN(sizeof(regs), size);
21
22 if (!size || size & (TRACEE_KLONGSIZE - 1)) {
23 printaddr(addr);
24 } else if (!umoven_or_printaddr(tcp, addr, fetch_size, ®s)) {
25 tprint_struct_begin();
26 PRINT_FIELD_ARRAY_UPTO(regs, gpr, fetch_size / TRACEE_KLONGSIZE,
27 tcp, print_xint_array_member);
28 if (fetch_size > offsetof(struct_prstatus_regset, nip)) {
29 tprint_struct_next();
30 PRINT_FIELD_X(regs, nip);
31 }
32 if (fetch_size > offsetof(struct_prstatus_regset, msr)) {
33 tprint_struct_next();
34 PRINT_FIELD_X(regs, msr);
35 }
36 if (fetch_size > offsetof(struct_prstatus_regset, orig_gpr3)) {
37 tprint_struct_next();
38 PRINT_FIELD_X(regs, orig_gpr3);
39 }
40 if (fetch_size > offsetof(struct_prstatus_regset, ctr)) {
41 tprint_struct_next();
42 PRINT_FIELD_X(regs, ctr);
43 }
44 if (fetch_size > offsetof(struct_prstatus_regset, link)) {
45 tprint_struct_next();
46 PRINT_FIELD_X(regs, link);
47 }
48 if (fetch_size > offsetof(struct_prstatus_regset, xer)) {
49 tprint_struct_next();
50 PRINT_FIELD_X(regs, xer);
51 }
52 if (fetch_size > offsetof(struct_prstatus_regset, ccr)) {
53 tprint_struct_next();
54 PRINT_FIELD_X(regs, ccr);
55 }
56 #if TRACEE_KLONGSIZE == 4
57 if (fetch_size > offsetof(struct_prstatus_regset, mq)) {
58 tprint_struct_next();
59 PRINT_FIELD_X(regs, mq);
60 }
61 #else
62 if (fetch_size > offsetof(struct_prstatus_regset, softe)) {
63 tprint_struct_next();
64 PRINT_FIELD_X(regs, softe);
65 }
66 #endif
67 if (fetch_size > offsetof(struct_prstatus_regset, trap)) {
68 tprint_struct_next();
69 PRINT_FIELD_X(regs, trap);
70 }
71 if (fetch_size > offsetof(struct_prstatus_regset, dar)) {
72 tprint_struct_next();
73 PRINT_FIELD_X(regs, dar);
74 }
75 if (fetch_size > offsetof(struct_prstatus_regset, dsisr)) {
76 tprint_struct_next();
77 PRINT_FIELD_X(regs, dsisr);
78 }
79 if (fetch_size > offsetof(struct_prstatus_regset, result)) {
80 tprint_struct_next();
81 PRINT_FIELD_X(regs, result);
82 }
83 if (size > sizeof(regs)) {
84 tprint_struct_next();
85 tprint_more_data_follows();
86 }
87 tprint_struct_end();
88 }
89 }
90
91 #undef TRACEE_KLONGSIZE