@@ -193,6 +193,109 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
193
193
return & user_csky_view ;
194
194
}
195
195
196
+ struct pt_regs_offset {
197
+ const char * name ;
198
+ int offset ;
199
+ };
200
+
201
+ #define REG_OFFSET_NAME (r ) {.name = #r, .offset = offsetof(struct pt_regs, r)}
202
+ #define REG_OFFSET_END {.name = NULL, .offset = 0}
203
+
204
+ static const struct pt_regs_offset regoffset_table [] = {
205
+ REG_OFFSET_NAME (tls ),
206
+ REG_OFFSET_NAME (lr ),
207
+ REG_OFFSET_NAME (pc ),
208
+ REG_OFFSET_NAME (sr ),
209
+ REG_OFFSET_NAME (usp ),
210
+ REG_OFFSET_NAME (orig_a0 ),
211
+ REG_OFFSET_NAME (a0 ),
212
+ REG_OFFSET_NAME (a1 ),
213
+ REG_OFFSET_NAME (a2 ),
214
+ REG_OFFSET_NAME (a3 ),
215
+ REG_OFFSET_NAME (regs [0 ]),
216
+ REG_OFFSET_NAME (regs [1 ]),
217
+ REG_OFFSET_NAME (regs [2 ]),
218
+ REG_OFFSET_NAME (regs [3 ]),
219
+ REG_OFFSET_NAME (regs [4 ]),
220
+ REG_OFFSET_NAME (regs [5 ]),
221
+ REG_OFFSET_NAME (regs [6 ]),
222
+ REG_OFFSET_NAME (regs [7 ]),
223
+ REG_OFFSET_NAME (regs [8 ]),
224
+ REG_OFFSET_NAME (regs [9 ]),
225
+ #if defined(__CSKYABIV2__ )
226
+ REG_OFFSET_NAME (exregs [0 ]),
227
+ REG_OFFSET_NAME (exregs [1 ]),
228
+ REG_OFFSET_NAME (exregs [2 ]),
229
+ REG_OFFSET_NAME (exregs [3 ]),
230
+ REG_OFFSET_NAME (exregs [4 ]),
231
+ REG_OFFSET_NAME (exregs [5 ]),
232
+ REG_OFFSET_NAME (exregs [6 ]),
233
+ REG_OFFSET_NAME (exregs [7 ]),
234
+ REG_OFFSET_NAME (exregs [8 ]),
235
+ REG_OFFSET_NAME (exregs [9 ]),
236
+ REG_OFFSET_NAME (exregs [10 ]),
237
+ REG_OFFSET_NAME (exregs [11 ]),
238
+ REG_OFFSET_NAME (exregs [12 ]),
239
+ REG_OFFSET_NAME (exregs [13 ]),
240
+ REG_OFFSET_NAME (exregs [14 ]),
241
+ REG_OFFSET_NAME (rhi ),
242
+ REG_OFFSET_NAME (rlo ),
243
+ REG_OFFSET_NAME (dcsr ),
244
+ #endif
245
+ REG_OFFSET_END ,
246
+ };
247
+
248
+ /**
249
+ * regs_query_register_offset() - query register offset from its name
250
+ * @name: the name of a register
251
+ *
252
+ * regs_query_register_offset() returns the offset of a register in struct
253
+ * pt_regs from its name. If the name is invalid, this returns -EINVAL;
254
+ */
255
+ int regs_query_register_offset (const char * name )
256
+ {
257
+ const struct pt_regs_offset * roff ;
258
+
259
+ for (roff = regoffset_table ; roff -> name != NULL ; roff ++ )
260
+ if (!strcmp (roff -> name , name ))
261
+ return roff -> offset ;
262
+ return - EINVAL ;
263
+ }
264
+
265
+ /**
266
+ * regs_within_kernel_stack() - check the address in the stack
267
+ * @regs: pt_regs which contains kernel stack pointer.
268
+ * @addr: address which is checked.
269
+ *
270
+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
271
+ * If @addr is within the kernel stack, it returns true. If not, returns false.
272
+ */
273
+ static bool regs_within_kernel_stack (struct pt_regs * regs , unsigned long addr )
274
+ {
275
+ return (addr & ~(THREAD_SIZE - 1 )) ==
276
+ (kernel_stack_pointer (regs ) & ~(THREAD_SIZE - 1 ));
277
+ }
278
+
279
+ /**
280
+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
281
+ * @regs: pt_regs which contains kernel stack pointer.
282
+ * @n: stack entry number.
283
+ *
284
+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
285
+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,
286
+ * this returns 0.
287
+ */
288
+ unsigned long regs_get_kernel_stack_nth (struct pt_regs * regs , unsigned int n )
289
+ {
290
+ unsigned long * addr = (unsigned long * )kernel_stack_pointer (regs );
291
+
292
+ addr += n ;
293
+ if (regs_within_kernel_stack (regs , (unsigned long )addr ))
294
+ return * addr ;
295
+ else
296
+ return 0 ;
297
+ }
298
+
196
299
void ptrace_disable (struct task_struct * child )
197
300
{
198
301
singlestep_disable (child );
0 commit comments