]> sourceware.org Git - systemtap.git/blame - tapset/s390/registers.stp
Rename CONTEXT regflags to probe_flags. Now simply indicates user mode.
[systemtap.git] / tapset / s390 / registers.stp
CommitLineData
4ff1e447
JK
1/* Dwarfless register access for s390x */
2
3global _reg_offsets, _stp_regs_registered
4
5function _stp_register_regs() {
6 /* Same order as pt_regs */
7 _reg_offsets["args"] = 0
8 _reg_offsets["psw.mask"] = 8
9 _reg_offsets["psw.addr"] = 16
10 _reg_offsets["r0"] = 24
11 _reg_offsets["r1"] = 32
12 _reg_offsets["r2"] = 40
13 _reg_offsets["r3"] = 48
14 _reg_offsets["r4"] = 56
15 _reg_offsets["r5"] = 64
16 _reg_offsets["r6"] = 72
17 _reg_offsets["r7"] = 80
18 _reg_offsets["r8"] = 88
19 _reg_offsets["r9"] = 96
20 _reg_offsets["r10"] = 104
21 _reg_offsets["r11"] = 112
22 _reg_offsets["r12"] = 120
23 _reg_offsets["r13"] = 128
24 _reg_offsets["r14"] = 136
25 _reg_offsets["r15"] = 144
26
27 _reg_offsets["orig_gpr2"] = 152
28 _reg_offsets["ilc"] = 160
29 _reg_offsets["trap"] = 162
30
31 /*
32 * If we ever need to support s390 (31-bit arch), we can
33 * get to the register offsets by using just a
34 * reg32_offset = _reg_offsets["reg"]/2
35 * or somesuch
36 */
37 _stp_regs_registered = 1
38}
39
40
41/*
42 * Though the flag says 31bit, asm-s390/thread_info.h comment
43 * says "32bit process"
44 */
45function probing_32bit_app() %{ /* pure */
46 if (CONTEXT->regs)
47 THIS->__retvalue = (user_mode(CONTEXT->regs) &&
48 test_tsk_thread_flag(current, TIF_31BIT));
49 else
50 THIS->__retvalue = 0;
51%}
52
92c25572
MW
53function _stp_probing_kernel: long () {
54 return !user_mode();
55}
4ff1e447
JK
56
57function _stp_get_register_by_offset:long (offset:long) %{ /* pure */
58 long value;
ba4e4ff4
JS
59 if (!CONTEXT->regs) {
60 CONTEXT->last_error = "No registers available in this context";
61 return;
62 }
63 if (THIS->offset < 0 || THIS->offset > sizeof(struct pt_regs) - sizeof(unsigned short)) {
64 snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
08fcfd65
DS
65 "Bad register offset: %lld",
66 (long long)THIS->offset);
ba4e4ff4
JS
67 CONTEXT->last_error = CONTEXT->error_buffer;
68 return;
69 }
4ff1e447 70
ba4e4ff4 71 if (THIS->offset < sizeof(struct pt_regs) - 2 * sizeof(unsigned short))
4ff1e447
JK
72 memcpy(&value, ((char *)CONTEXT->regs) + THIS->offset,
73 sizeof(value));
74 else {
75 /* ilc or trap */
76 unsigned short us_value;
77 memcpy(&us_value, ((char *)CONTEXT->regs) + THIS->offset,
78 sizeof(us_value));
79 value = us_value; // not sign-extended
80 }
81 THIS->__retvalue = value;
82%}
83
84function _stp_sign_extend32:long (value:long) {
85 if (value & 0x80000000)
86 value |= (0xffffffff << 32)
87 return value
88}
89
90function _stp_register:long (name:string, sign_extend:long) {
91 if (!registers_valid()) {
92 error("cannot access CPU registers in this context")
93 return 0
94 }
95 if (!_stp_regs_registered)
96 _stp_register_regs()
97 offset = _reg_offsets[name]
98 if (offset == 0 && !(name in _reg_offsets)) {
99 error("Unknown register: " . name)
100 return 0
101 }
102 value = _stp_get_register_by_offset(offset)
103 if (probing_32bit_app()) {
104 if (sign_extend)
105 value = _stp_sign_extend32(value)
106 else
107 value &= 0xffffffff
108 }
109 return value
110}
111
112/* Return the named register value as a signed value. */
113function register:long (name:string) {
114 return _stp_register(name, 1)
115}
116
117/*
118 * Return the named register value as an unsigned value. Specifically,
119 * don't sign-extend the register value when promoting it to 64 bits.
120 */
121function u_register:long (name:string) {
122 return _stp_register(name, 0)
123}
124
125/*
126 * Return the value of function arg #argnum (1=first arg).
127 * If truncate=1, mask off the top 32 bits.
128 * If sign_extend=1 and (truncate=1 or the probepoint we've hit is in a
129 * 32-bit app), sign-extend the 32-bit value.
130 *
131 * We don't yet support extracting arg #6 and beyond, which are passed
132 * on stack
133 */
134function _stp_arg:long (argnum:long, sign_extend:long, truncate:long) {
135 val = 0
136 if (argnum < 1 || argnum > 5) {
137 error(sprintf("Cannot access arg(%d)", argnum))
138 return 0
139 }
140
141 if (argnum == 1)
142 val = u_register("r2")
143 else if (argnum == 2)
144 val = u_register("r3")
145 else if (argnum == 3)
146 val = u_register("r4")
147 else if (argnum == 4)
148 val = u_register("r5")
903dc69f 149 else if (argnum == 5)
4ff1e447
JK
150 val = u_register("r6")
151
152 if (truncate) {
153 if (sign_extend)
154 val = _stp_sign_extend32(val)
155 else
156 /* High bits may be garbage. */
157 val = (val & 0xffffffff);
158 }
159 return val;
160}
161
162/* Return the value of function arg #argnum (1=first arg) as a signed int. */
163function int_arg:long (argnum:long) {
164 return _stp_arg(argnum, 1, 1)
165}
166
167/* Return the value of function arg #argnum (1=first arg) as an unsigned int. */
168function uint_arg:long (argnum:long) {
169 return _stp_arg(argnum, 0, 1)
170}
171
172function long_arg:long (argnum:long) {
173 return _stp_arg(argnum, 1, 0)
174}
175
176function ulong_arg:long (argnum:long) {
177 return _stp_arg(argnum, 0, 0)
178}
179
180function longlong_arg:long (argnum:long) {
181 if (probing_32bit_app()) {
182 /* TODO verify if this is correct for 31bit apps */
183 highbits = _stp_arg(argnum, 0, 1)
184 lowbits = _stp_arg(argnum+1, 0, 1)
185 return ((highbits << 32) | lowbits)
186 } else
187 return _stp_arg(argnum, 0, 0)
188}
189
190function ulonglong_arg:long (argnum:long) {
191 return longlong_arg(argnum)
192}
193
194function pointer_arg:long (argnum:long) {
195 return _stp_arg(argnum, 0, 0)
196}
197
198function s32_arg:long (argnum:long) {
199 return int_arg(argnum)
200}
201
202function u32_arg:long (argnum:long) {
203 return uint_arg(argnum)
204}
205
206function s64_arg:long (argnum:long) {
207 return longlong_arg(argnum)
208}
209
210function u64_arg:long (argnum:long) {
211 return ulonglong_arg(argnum)
212}
213
29d0edeb 214function asmlinkage() %{ /* pure */ %}
4ff1e447 215
29d0edeb 216function fastcall() %{ /* pure */ %}
4ff1e447 217
309d67d8 218function regparm(n:long) %{
4ff1e447
JK
219 snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
220 "regparm is invalid on s390.");
221 CONTEXT->last_error = CONTEXT->error_buffer;
222%}
This page took 0.098387 seconds and 5 git commands to generate.