1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
|
#ifndef _DBI_ASM_ARM_KPROBES_H
#define _DBI_ASM_ARM_KPROBES_H
/*
* Dynamic Binary Instrumentation Module based on KProbes
* modules/kprobe/arch/asm-arm/dbi_kprobes.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Copyright (C) Samsung Electronics, 2006-2010
*
* 2006-2007 Ekaterina Gorelkina <e.gorelkina@samsung.com>: initial implementation for ARM/MIPS
* 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
* Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
* 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
*
* 2010-2011 Alexander Shirshikov <a.shirshikov@samsung.com>: initial implementation for Thumb
*/
#include <linux/sched.h>
#include <linux/compiler.h>
typedef unsigned long kprobe_opcode_t;
#ifdef CONFIG_CPU_S3C2443
#define BREAKPOINT_INSTRUCTION 0xe1200070
#else
#define BREAKPOINT_INSTRUCTION 0xffffdeff
#endif /* CONFIG_CPU_S3C2443 */
#ifndef KPROBES_RET_PROBE_TRAMP
#ifdef CONFIG_CPU_S3C2443
#define UNDEF_INSTRUCTION 0xe1200071
#else
#define UNDEF_INSTRUCTION 0xfffffffe
#endif /* CONFIG_CPU_S3C2443 */
#endif /* KPROBES_RET_PROBE_TRAMP */
#define MAX_INSN_SIZE 1
#define UPROBES_TRAMP_LEN 9 * 4
# define UPROBES_TRAMP_INSN_IDX 2
# define UPROBES_TRAMP_SS_BREAK_IDX 4
# define UPROBES_TRAMP_RET_BREAK_IDX 5
#define KPROBES_TRAMP_LEN 9 * 4
# define KPROBES_TRAMP_INSN_IDX UPROBES_TRAMP_INSN_IDX
# define KPROBES_TRAMP_SS_BREAK_IDX UPROBES_TRAMP_SS_BREAK_IDX
/* TODO: remove (not needed for kprobe) */
# define KPROBES_TRAMP_RET_BREAK_IDX UPROBES_TRAMP_RET_BREAK_IDX
#define UREGS_OFFSET 8
struct prev_kprobe {
struct kprobe *kp;
unsigned long status;
};
static inline unsigned long arch_get_task_pc(struct task_struct *p)
{
return task_thread_info(p)->cpu_context.pc;
}
static inline void arch_set_task_pc(struct task_struct *p, unsigned long val)
{
task_thread_info(p)->cpu_context.pc = val;
}
static inline struct pt_regs *dbi_get_syscall_uregs(unsigned long sp)
{
return (struct pt_regs *)(sp + UREGS_OFFSET);
}
static inline unsigned long dbi_get_stack_ptr(struct pt_regs *regs)
{
return regs->ARM_sp;
}
static inline unsigned long dbi_get_instr_ptr(struct pt_regs *regs)
{
return regs->ARM_pc;
}
static inline void dbi_set_instr_ptr(struct pt_regs *regs, unsigned long val)
{
regs->ARM_pc = val;
}
static inline unsigned long dbi_get_ret_addr(struct pt_regs *regs)
{
return regs->ARM_lr;
}
static inline void dbi_set_ret_addr(struct pt_regs *regs, unsigned long val)
{
regs->ARM_lr = val;
}
static inline unsigned long dbi_get_arg(struct pt_regs *regs, int num)
{
return regs->uregs[num];
}
static inline void dbi_set_arg(struct pt_regs *regs, int num, unsigned long val)
{
regs->uregs[num] = val;
}
// undefined
# define MASK_ARM_INSN_UNDEF 0x0FF00000 // xxxx1111 1111xxxx xxxxxxxx xxxxxxxx
# define PTRN_ARM_INSN_UNDEF 0x03000000 // cccc0011 0000xxxx xxxxxxxx xxxxxxxx
# define MASK_THUMB_INSN_UNDEF 0xFE00 // 11111111xxxxxxxx
# define PTRN_THUMB_INSN_UNDEF 0xDE00 // 11011110xxxxxxxx
// architecturally undefined
# define MASK_ARM_INSN_AUNDEF 0x0FF000F0
# define PTRN_ARM_INSN_AUNDEF 0x07F000F0
// branches
# define MASK_ARM_INSN_B 0x0F000000 // xxxx1111xxxxxxxxxxxxxxxxxxxxxxxx
# define PTRN_ARM_INSN_B 0x0A000000 // cccc1010xxxxxxxxxxxxxxxxxxxxxxxx
# define MASK_THUMB_INSN_B1 0xF000 // 1111xxxxxxxxxxxx
# define PTRN_THUMB_INSN_B1 0xD000 // 1101xxxxxxxxxxxx // b<cond> label
# define MASK_THUMB_INSN_B2 0xF800 // 11111xxxxxxxxxxx
# define PTRN_THUMB_INSN_B2 0xE000 // 11100xxxxxxxxxxx // b label
# define MASK_THUMB_INSN_CBZ 0xF500 // 1111x1x1xxxxxxxx
# define PTRN_THUMB_INSN_CBZ 0xB100 // 1011x0x1xxxxxxxx // CBZ/CBNZ
# define MASK_THUMB2_INSN_B1 0xD000F800 // 11x1xxxxxxxxxxxx 11111xxxxxxxxxxx // swapped
# define PTRN_THUMB2_INSN_B1 0x8000F000 // 10x0xxxxxxxxxxxx 11110xxxxxxxxxxx // swapped
# define MASK_THUMB2_INSN_B2 0xD000F800 // 11x1xxxxxxxxxxxx 11111xxxxxxxxxxx // swapped
# define PTRN_THUMB2_INSN_B2 0x9000F000 // 10x1xxxxxxxxxxxx 11110xxxxxxxxxxx // swapped
# define MASK_ARM_INSN_BL 0x0F000000 // xxxx1111xxxxxxxxxxxxxxxxxxxxxxxx
# define PTRN_ARM_INSN_BL 0x0B000000 // cccc1011xxxxxxxxxxxxxxxxxxxxxxxx
//# define MASK_THUMB_INSN_BL 0xF800 // 11111xxxxxxxxxxx
//# define PTRN_THUMB_INSN_BL 0xF000 // 11110xxxxxxxxxxx // shared between BL and BLX
//# define PTRN_THUMB_INSN_BL 0xF800 // 11111xxxxxxxxxxx
# define MASK_THUMB2_INSN_BL 0xD000F800 // 11x1xxxxxxxxxxxx 11111xxxxxxxxxxx // swapped
# define PTRN_THUMB2_INSN_BL 0xD000F000 // 11x1xxxxxxxxxxxx 11110xxxxxxxxxxx // bl imm swapped
# define MASK_ARM_INSN_BLX1 0xFE000000 // 1111111axxxxxxxxxxxxxxxxxxxxxxxx
# define PTRN_ARM_INSN_BLX1 0xFA000000 // 1111101axxxxxxxxxxxxxxxxxxxxxxxx
//# define MASK_THUMB_INSN_BLX1 0xF800 // 11111xxxxxxxxxxx / blx imm
//# define PTRN_THUMB_INSN_BLX1 0xF000 // 11101xxxxxxxxxxx
# define MASK_THUMB2_INSN_BLX1 0xD001F800 // 11x1xxxxxxxxxxx1 11111xxxxxxxxxxx // swapped
# define PTRN_THUMB2_INSN_BLX1 0xC000F000 // 11x0xxxxxxxxxxx0 11110xxxxxxxxxxx // swapped
# define MASK_ARM_INSN_BLX2 0x0FF000F0 // xxxx11111111xxxxxxxxxxxx1111xxxx
# define PTRN_ARM_INSN_BLX2 0x01200030 // cccc00010010xxxxxxxxxxxx0011xxxx
# define MASK_THUMB_INSN_BLX2 0xFF80 // 111111111xxxxxxx / blx reg
# define PTRN_THUMB_INSN_BLX2 0x4780 // 010001111xxxxxxx
# define MASK_ARM_INSN_BX 0x0FF000F0 // cccc11111111xxxxxxxxxxxx1111xxxx
# define PTRN_ARM_INSN_BX 0x01200010 // cccc00010010xxxxxxxxxxxx0001xxxx
# define MASK_THUMB_INSN_BX 0xFF80 // 111111111xxxxxxx
# define PTRN_THUMB_INSN_BX 0x4700 // 010001110xxxxxxx
# define MASK_ARM_INSN_BXJ 0x0FF000F0 // xxxx11111111xxxxxxxxxxxx1111xxxx
# define PTRN_ARM_INSN_BXJ 0x01200020 // cccc00010010xxxxxxxxxxxx0010xxxx
# define MASK_THUMB2_INSN_BXJ 0xD000FFF0 // 11x1xxxxxxxxxxxx 111111111111xxxx // swapped
# define PTRN_THUMB2_INSN_BXJ 0x8000F3C0 // 10x0xxxxxxxxxxxx 111100111100xxxx // swapped
// software interrupts
# define MASK_ARM_INSN_SWI 0x0F000000 // cccc1111xxxxxxxxxxxxxxxxxxxxxxxx
# define PTRN_ARM_INSN_SWI 0x0F000000 // cccc1111xxxxxxxxxxxxxxxxxxxxxxxx
# define MASK_THUMB_INSN_SWI 0xFF00 // 11111111xxxxxxxx
# define PTRN_THUMB_INSN_SWI 0xDF00 // 11011111xxxxxxxx
// break
# define MASK_ARM_INSN_BREAK 0xFFF000F0 // 111111111111xxxxxxxxxxxx1111xxxx
# define PTRN_ARM_INSN_BREAK 0xE1200070 // 111000010010xxxxxxxxxxxx0111xxxx /? A8-56 ARM DDI 046B if cond != ‘1110’ then UNPREDICTABLE;
# define MASK_THUMB_INSN_BREAK 0xFF00 // 11111111xxxxxxxx
# define PTRN_THUMB_INSN_BREAK 0xBE00 // 10111110xxxxxxxx
// CLZ
# define MASK_ARM_INSN_CLZ 0x0FFF0FF0 // xxxx111111111111xxxx11111111xxxx
# define PTRN_ARM_INSN_CLZ 0x016F0F10 // cccc000101101111xxxx11110001xxxx
// Data processing immediate shift
# define MASK_ARM_INSN_DPIS 0x0E000010
# define PTRN_ARM_INSN_DPIS 0x00000000
// Data processing register shift
# define MASK_ARM_INSN_DPRS 0x0E000090
# define PTRN_ARM_INSN_DPRS 0x00000010
# define MASK_THUMB2_INSN_DPRS 0xFFE00000 // 11111111111xxxxxxxxxxxxxxxxxxxxx
# define PTRN_THUMB2_INSN_DPRS 0xEA000000 // 1110101xxxxxxxxxxxxxxxxxxxxxxxxx
// Data processing immediate
# define MASK_ARM_INSN_DPI 0x0E000000
# define PTRN_ARM_INSN_DPI 0x02000000
# define MASK_THUMB_INSN_DP 0xFC00 // 111111xxxxxxxxxx
# define PTRN_THUMB_INSN_DP 0x4000 // 010000xxxxxxxxxx
# define MASK_THUMB_INSN_APC 0xF800 // 11111xxxxxxxxxxx
# define PTRN_THUMB_INSN_APC 0xA000 // 10100xxxxxxxxxxx ADD Rd, [PC, #<imm8> * 4]
# define MASK_THUMB2_INSN_DPI 0xFBE08000 // 11111x11111xxxxx 1xxxxxxxxxxxxxxx
//# define PTRN_THUMB2_INSN_DPI 0xF0000000 // 11110x0xxxxxxxxx 0xxxxxxxxxxxxxxx /? A6-19 ARM DDI 0406B
# define PTRN_THUMB2_INSN_DPI 0xF2000000 // 11110x1xxxxxxxxx 0xxxxxxxxxxxxxxx /? A6-19 ARM DDI 0406B
# define MASK_THUMB_INSN_MOV3 0xFF00 // 11111111xxxxxxxx
# define PTRN_THUMB_INSN_MOV3 0x4600 // 01000110xxxxxxxx MOV Rd, PC
# define MASK_THUMB2_INSN_RSBW 0x8000fbe0 // 1xxxxxxxxxxxxxxx 11111x11111xxxxx // swapped
# define PTRN_THUMB2_INSN_RSBW 0x0000f1c0 // 0xxxxxxxxxxxxxxx 11110x01110xxxxx RSB{S}.W Rd, Rn, #<const> // swapped
# define MASK_THUMB2_INSN_RORW 0xf0f0ffe0 // 1111xxxx1111xxxx 11111111111xxxxx // swapped
# define PTRN_THUMB2_INSN_RORW 0xf000fa60 // 1111xxxx0000xxxx 11111010011xxxxx ROR{S}.W Rd, Rn, Rm // swapped
# define MASK_THUMB2_INSN_ROR 0x0030ffef // xxxxxxxxxx11xxxx 11111111111x1111 // swapped
# define PTRN_THUMB2_INSN_ROR 0x0030ea4f // xxxxxxxxxx11xxxx 11101010010x1111 ROR{S} Rd, Rm, #<imm> // swapped
# define MASK_THUMB2_INSN_LSLW1 0xf0f0ffe0 // 1111xxxx1111xxxx 11111111111xxxxx // swapped
# define PTRN_THUMB2_INSN_LSLW1 0xf000fa00 // 1111xxxx0000xxxx 11111010000xxxxx LSL{S}.W Rd, Rn, Rm // swapped
# define MASK_THUMB2_INSN_LSLW2 0x0030ffef // xxxxxxxxxx11xxxx 11111111111x1111 // swapped
# define PTRN_THUMB2_INSN_LSLW2 0x0000ea4f // xxxxxxxxxx00xxxx 11101010010x1111 LSL{S}.W Rd, Rm, #<imm5> // swapped
# define MASK_THUMB2_INSN_LSRW1 0xf0f0ffe0 // 1111xxxx1111xxxx 11111111111xxxxx // swapped
# define PTRN_THUMB2_INSN_LSRW1 0xf000fa20 // 1111xxxx0000xxxx 11111010001xxxxx LSR{S}.W Rd, Rn, Rm // swapped
# define MASK_THUMB2_INSN_LSRW2 0x0030ffef // xxxxxxxxxx11xxxx 11111111111x1111 // swapped
# define PTRN_THUMB2_INSN_LSRW2 0x0010ea4f // xxxxxxxxxx01xxxx 11101010010x1111 LSR{S}.W Rd, Rm, #<imm5> // swapped
# define MASK_THUMB2_INSN_TEQ1 0x8f00fbf0 // 1xxx1111xxxxxxxx 11111x111111xxxx // swapped
# define PTRN_THUMB2_INSN_TEQ1 0x0f00f090 // 0xxx1111xxxxxxxx 11110x001001xxxx TEQ Rn, #<const> // swapped
# define MASK_THUMB2_INSN_TEQ2 0x0f00fff0 // xxxx1111xxxxxxxx 111111111111xxxx // swapped
# define PTRN_THUMB2_INSN_TEQ2 0x0f00ea90 // xxxx1111xxxxxxxx 111010101001xxxx TEQ Rn, Rm{,<shift>} // swapped
# define MASK_THUMB2_INSN_TST1 0x8f00fbf0 // 1xxx1111xxxxxxxx 11111x111111xxxx // swapped
# define PTRN_THUMB2_INSN_TST1 0x0f00f010 // 0xxx1111xxxxxxxx 11110x000001xxxx TST Rn, #<const> // swapped
# define MASK_THUMB2_INSN_TST2 0x0f00fff0 // xxxx1111xxxxxxxx 111111111111xxxx // swapped
# define PTRN_THUMB2_INSN_TST2 0x0f00ea10 // xxxx1111xxxxxxxx 111010100001xxxx TST Rn, Rm{,<shift>} // swapped
// Load immediate offset
# define MASK_ARM_INSN_LIO 0x0E100000
# define PTRN_ARM_INSN_LIO 0x04100000
# define MASK_THUMB_INSN_LIO1 0xF800 // 11111xxxxxxxxxxx
# define PTRN_THUMB_INSN_LIO1 0x6800 // 01101xxxxxxxxxxx LDR
# define MASK_THUMB_INSN_LIO2 MASK_THUMB_INSN_LIO1
# define PTRN_THUMB_INSN_LIO2 0x7800 // 01111xxxxxxxxxxx LDRB
# define MASK_THUMB_INSN_LIO3 MASK_THUMB_INSN_LIO1
# define PTRN_THUMB_INSN_LIO3 0x8800 // 10001xxxxxxxxxxx LDRH
# define MASK_THUMB_INSN_LIO4 MASK_THUMB_INSN_LIO1
# define PTRN_THUMB_INSN_LIO4 0x9800 // 10011xxxxxxxxxxx LDR SP relative
# define MASK_THUMB2_INSN_LDRW 0x0000fff0 // xxxxxxxxxxxxxxxx 111111111111xxxx // swapped
# define PTRN_THUMB2_INSN_LDRW 0x0000f850 // xxxxxxxxxxxxxxxx 111110000101xxxx LDR.W Rt, [Rn, #-<imm12>]// swapped
# define MASK_THUMB2_INSN_LDRW1 MASK_THUMB2_INSN_LDRW
# define PTRN_THUMB2_INSN_LDRW1 0x0000f8d0 // xxxxxxxxxxxxxxxx 111110001101xxxx LDR.W Rt, [Rn, #<imm12>]// swapped
# define MASK_THUMB2_INSN_LDRBW MASK_THUMB2_INSN_LDRW
# define PTRN_THUMB2_INSN_LDRBW 0x0000f810 // xxxxxxxxxxxxxxxx 111110000001xxxx LDRB.W Rt, [Rn, #-<imm8>]// swapped
# define MASK_THUMB2_INSN_LDRBW1 MASK_THUMB2_INSN_LDRW
# define PTRN_THUMB2_INSN_LDRBW1 0x0000f890 // xxxxxxxxxxxxxxxx 111110001001xxxx LDRB.W Rt, [Rn, #<imm12>]// swapped
# define MASK_THUMB2_INSN_LDRHW MASK_THUMB2_INSN_LDRW
# define PTRN_THUMB2_INSN_LDRHW 0x0000f830 // xxxxxxxxxxxxxxxx 111110000011xxxx LDRH.W Rt, [Rn, #-<imm8>]// swapped
# define MASK_THUMB2_INSN_LDRHW1 MASK_THUMB2_INSN_LDRW
# define PTRN_THUMB2_INSN_LDRHW1 0x0000f8b0 // xxxxxxxxxxxxxxxx 111110001011xxxx LDRH.W Rt, [Rn, #<imm12>]// swapped
# define MASK_THUMB2_INSN_LDRD 0x0000fed0 // xxxxxxxxxxxxxxxx 1111111x11x1xxxx // swapped
# define PTRN_THUMB2_INSN_LDRD 0x0000e850 // xxxxxxxxxxxxxxxx 1110100x01x1xxxx LDRD Rt, Rt2, [Rn, #-<imm8>]// swapped
# define MASK_THUMB2_INSN_LDRD1 MASK_THUMB2_INSN_LDRD
# define PTRN_THUMB2_INSN_LDRD1 0x0000e8d0 // xxxxxxxxxxxxxxxx 1110100x11x1xxxx LDRD Rt, Rt2, [Rn, #<imm8>]// swapped
# define MASK_THUMB2_INSN_LDRWL 0x0fc0fff0 // xxxx111111xxxxxx 111111111111xxxx // swapped
# define PTRN_THUMB2_INSN_LDRWL 0x0000f850 // xxxxxxxxxxxxxxxx 111110000101xxxx LDR.W Rt, [Rn, Rm, LSL #<imm2>]// swapped
# define MASK_THUMB2_INSN_LDREX 0x0f00ffff // xxxx1111xxxxxxxx 1111111111111111 // swapped
# define PTRN_THUMB2_INSN_LDREX 0x0f00e85f // xxxx1111xxxxxxxx 1110100001011111 LDREX Rt, [PC, #<imm8>]// swapped
# define MASK_THUMB2_INSN_MUL 0xf0f0fff0 // 1111xxxx1111xxxx 111111111111xxxx // swapped
# define PTRN_THUMB2_INSN_MUL 0xf000fb00 // 1111xxxx0000xxxx 111110110000xxxx MUL Rd, Rn, Rm// swapped
# define MASK_THUMB2_INSN_DP 0x0000ff00 // xxxxxxxxxxxxxxxx 11111111xxxxxxxx // swapped
# define PTRN_THUMB2_INSN_DP 0x0000eb00 // xxxxxxxxxxxxxxxx 11101011xxxxxxxx // swapped ADD/SUB/SBC/...Rd, Rn, Rm{,<shift>}
// Store immediate offset
# define MASK_ARM_INSN_SIO MASK_ARM_INSN_LIO
# define PTRN_ARM_INSN_SIO 0x04000000
# define MASK_THUMB_INSN_SIO1 MASK_THUMB_INSN_LIO1
# define PTRN_THUMB_INSN_SIO1 0x6000 // 01100xxxxxxxxxxx STR
# define MASK_THUMB_INSN_SIO2 MASK_THUMB_INSN_LIO1
# define PTRN_THUMB_INSN_SIO2 0x7000 // 01110xxxxxxxxxxx STRB
# define MASK_THUMB_INSN_SIO3 MASK_THUMB_INSN_LIO1
# define PTRN_THUMB_INSN_SIO3 0x8000 // 10000xxxxxxxxxxx STRH
# define MASK_THUMB_INSN_SIO4 MASK_THUMB_INSN_LIO1
# define PTRN_THUMB_INSN_SIO4 0x9000 // 10010xxxxxxxxxxx STR SP relative
# define MASK_THUMB2_INSN_STRW 0x0fc0fff0 // xxxx111111xxxxxx 111111111111xxxx // swapped
# define PTRN_THUMB2_INSN_STRW 0x0000f840 // xxxx000000xxxxxx 111110000100xxxx STR.W Rt, [Rn, Rm, {LSL #<imm2>}]// swapped
# define MASK_THUMB2_INSN_STRW1 0x0000fff0 // xxxxxxxxxxxxxxxx 111111111111xxxx // swapped
# define PTRN_THUMB2_INSN_STRW1 0x0000f8c0 // xxxxxxxxxxxxxxxx 111110001100xxxx STR.W Rt, [Rn, #imm12]// swapped // STR.W Rt, [PC, #imm12] shall be skipped, because it hangs on Tegra. WTF
# define MASK_THUMB2_INSN_STRHW MASK_THUMB2_INSN_STRW
# define PTRN_THUMB2_INSN_STRHW 0x0000f820 // xxxx000000xxxxxx 111110000010xxxx STRH.W Rt, [Rn, Rm, {LSL #<imm2>}]// swapped
# define MASK_THUMB2_INSN_STRHW1 0x0000fff0 // xxxxxxxxxxxxxxxx 111111111111xxxx // swapped
# define PTRN_THUMB2_INSN_STRHW1 0x0000f8a0 // xxxxxxxxxxxxxxxx 111110001010xxxx STRH.W Rt, [Rn, #<imm12>]// swapped
# define MASK_THUMB2_INSN_STRHT 0x0f00fff0 // xxxx1111xxxxxxxx 111111111111xxxx // swapped // strht r1, [pc, #imm] illegal instruction on Tegra. WTF
# define PTRN_THUMB2_INSN_STRHT 0x0e00f820 // xxxx1110xxxxxxxx 111110000010xxxx STRHT Rt, [Rn, #<imm8>]// swapped
# define MASK_THUMB2_INSN_STRT 0x0f00fff0 // xxxx1111xxxxxxxx 111111111111xxxx // swapped
# define PTRN_THUMB2_INSN_STRT 0x0e00f840 // xxxx1110xxxxxxxx 111110000100xxxx STRT Rt, [Rn, #<imm8>]// swapped
# define MASK_THUMB2_INSN_STRBW MASK_THUMB2_INSN_STRW // xxxx111111xxxxxx 111111111111xxxx // swapped
# define PTRN_THUMB2_INSN_STRBW 0x0000f800 // xxxx000000xxxxxx 111110000100xxxx STRB.W Rt, [Rn, Rm, {LSL #<imm2>}]// swapped
# define MASK_THUMB2_INSN_STRBW1 0x0000fff0 // xxxxxxxxxxxxxxxx 111111111111xxxx // swapped
# define PTRN_THUMB2_INSN_STRBW1 0x0000f880 // xxxxxxxxxxxxxxxx 111110001000xxxx STRB.W Rt, [Rn, #<imm12>]// swapped // STRB.W Rt, [PC, #imm12] shall be skipped, because it hangs on Tegra. WTF
# define MASK_THUMB2_INSN_STRBT 0x0f00fff0 // xxxx1111xxxxxxxx 111111111111xxxx // swapped
# define PTRN_THUMB2_INSN_STRBT 0x0e00f800 // xxxx1110xxxxxxxx 111110000000xxxx STRBT Rt, [Rn, #<imm8>}]// swapped
# define MASK_THUMB2_INSN_STRD 0x0000fe50 // xxxxxxxxxxxxxxxx 1111111xx1x1xxxx // swapped
# define PTRN_THUMB2_INSN_STRD 0x0000e840 // xxxxxxxxxxxxxxxx 1110100xx1x0xxxx STR{D, EX, EXB, EXH, EXD} Rt, Rt2, [Rn, #<imm8>]// swapped
// Load register offset
# define MASK_ARM_INSN_LRO 0x0E100010
# define PTRN_ARM_INSN_LRO 0x06100000
# define MASK_THUMB_INSN_LRO1 0xFE00 // 1111111xxxxxxxxx
# define PTRN_THUMB_INSN_LRO1 0x5600 // 0101011xxxxxxxxx LDRSB
# define MASK_THUMB_INSN_LRO2 MASK_THUMB_INSN_LRO1
# define PTRN_THUMB_INSN_LRO2 0x5800 // 0101100xxxxxxxxx LDR
# define MASK_THUMB_INSN_LRO3 0xf800 // 11111xxxxxxxxxxx
# define PTRN_THUMB_INSN_LRO3 0x4800 // 01001xxxxxxxxxxx LDR Rd, [PC, #<imm8> * 4]
# define MASK_THUMB_INSN_LRO4 MASK_THUMB_INSN_LRO1
# define PTRN_THUMB_INSN_LRO4 0x5A00 // 0101101xxxxxxxxx LDRH
# define MASK_THUMB_INSN_LRO5 MASK_THUMB_INSN_LRO1
# define PTRN_THUMB_INSN_LRO5 0x5C00 // 0101110xxxxxxxxx LDRB
# define MASK_THUMB_INSN_LRO6 MASK_THUMB_INSN_LRO1
# define PTRN_THUMB_INSN_LRO6 0x5E00 // 0101111xxxxxxxxx LDRSH
# define MASK_THUMB2_INSN_ADR 0x8000fa1f // 1xxxxxxxxxxxxxxx 11111x1xxxx11111 // swapped
# define PTRN_THUMB2_INSN_ADR 0x0000f20f // 0xxxxxxxxxxxxxxx 11110x1xxxx01111 // swapped
// Store register offset
# define MASK_ARM_INSN_SRO MASK_ARM_INSN_LRO
# define PTRN_ARM_INSN_SRO 0x06000000
# define MASK_THUMB_INSN_SRO1 MASK_THUMB_INSN_LRO1
# define PTRN_THUMB_INSN_SRO1 0x5000 // 0101000xxxxxxxxx STR
# define MASK_THUMB_INSN_SRO2 MASK_THUMB_INSN_LRO1
# define PTRN_THUMB_INSN_SRO2 0x5200 // 0101001xxxxxxxxx STRH
# define MASK_THUMB_INSN_SRO3 MASK_THUMB_INSN_LRO1
# define PTRN_THUMB_INSN_SRO3 0x5400 // 0101010xxxxxxxxx STRB
// Load multiple
# define MASK_ARM_INSN_LM 0x0E100000
# define PTRN_ARM_INSN_LM 0x08100000
# define MASK_THUMB2_INSN_LDMIA 0x8000ffd0 // 1xxxxxxxxxxxxxxx 1111111111x1xxxx // swapped
# define PTRN_THUMB2_INSN_LDMIA 0x8000e890 // 1xxxxxxxxxxxxxxx 1110100010x1xxxx LDMIA(.W) Rn(!), {Rx, ..., PC}// swapped
# define MASK_THUMB2_INSN_LDMDB 0x8000ffd0 // 1xxxxxxxxxxxxxxx 1111111111x1xxxx // swapped
# define PTRN_THUMB2_INSN_LDMDB 0x8000e910 // 1xxxxxxxxxxxxxxx 1110100100x1xxxx LDMDB(.W) Rn(!), {Rx, ..., PC}// swapped
// Store multiple
# define MASK_ARM_INSN_SM MASK_ARM_INSN_LM
# define PTRN_ARM_INSN_SM 0x08000000
// Coprocessor load/store and double register transfers
# define MASK_ARM_INSN_CLS 0x0E000000
# define PTRN_ARM_INSN_CLS 0x0C000000
// Coprocessor register transfers
# define MASK_ARM_INSN_CRT 0x0F000010
# define PTRN_ARM_INSN_CRT 0x0E000010
# define ARM_INSN_MATCH(name, insn) ((insn & MASK_ARM_INSN_##name) == PTRN_ARM_INSN_##name)
# define THUMB_INSN_MATCH(name, insn) (((insn & 0x0000FFFF) & MASK_THUMB_INSN_##name) == PTRN_THUMB_INSN_##name)
# define THUMB2_INSN_MATCH(name, insn) ((insn & MASK_THUMB2_INSN_##name) == PTRN_THUMB2_INSN_##name)
# define ARM_INSN_REG_RN(insn) ((insn & 0x000F0000)>>16)
# define ARM_INSN_REG_SET_RN(insn, nreg) {insn &= ~0x000F0000; insn |= nreg<<16;}
# define ARM_INSN_REG_RD(insn) ((insn & 0x0000F000)>>12)
# define ARM_INSN_REG_SET_RD(insn, nreg) {insn &= ~0x0000F000; insn |= nreg<<12;}
# define ARM_INSN_REG_RS(insn) ((insn & 0x00000F00)>>8)
# define ARM_INSN_REG_SET_RS(insn, nreg) {insn &= ~0x00000F00; insn |= nreg<<8;}
# define ARM_INSN_REG_RM(insn) (insn & 0x0000000F)
# define ARM_INSN_REG_SET_RM(insn, nreg) {insn &= ~0x0000000F; insn |= nreg;}
# define ARM_INSN_REG_MR(insn, nreg) (insn & (1 << nreg))
# define ARM_INSN_REG_SET_MR(insn, nreg) {insn |= (1 << nreg);}
# define ARM_INSN_REG_CLEAR_MR(insn, nreg) {insn &= ~(1 << nreg);}
# define THUMB2_INSN_REG_RT(insn) ((insn & 0xf0000000) >> 28)
# define THUMB2_INSN_REG_RT2(insn) ((insn & 0x0f000000) >> 24)
# define THUMB2_INSN_REG_RN(insn) (insn & 0x0000000f)
# define THUMB2_INSN_REG_RD(insn) ((insn & 0x0f000000) >> 24)
# define THUMB2_INSN_REG_RM(insn) ((insn & 0x000f0000) >> 16)
/* per-cpu kprobe control block */
struct kprobe_ctlblk {
unsigned long kprobe_status;
struct prev_kprobe prev_kprobe;
};
/* Architecture specific copy of original instruction */
struct arch_specific_insn {
/* copy of the original instruction */
kprobe_opcode_t *insn;
};
typedef kprobe_opcode_t (*entry_point_t) (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
struct undef_hook;
void swap_register_undef_hook(struct undef_hook *hook);
void swap_unregister_undef_hook(struct undef_hook *hook);
static inline int arch_init_module_deps(void)
{
return 0;
}
int arch_make_trampoline_arm(unsigned long addr, unsigned long insn,
unsigned long *tramp);
struct slot_manager;
struct kretprobe;
struct kretprobe_instance;
int arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm);
void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs);
void arch_arm_kprobe(struct kprobe *p);
void arch_disarm_kprobe(struct kprobe *p);
int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs);
int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs);
void save_previous_kprobe(struct kprobe_ctlblk *kcb, struct kprobe *cur_p);
void restore_previous_kprobe(struct kprobe_ctlblk *kcb);
void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb);
void __naked kretprobe_trampoline(void);
static inline unsigned long swap_get_karg(struct pt_regs *regs, unsigned long n)
{
switch (n) {
case 0:
return regs->ARM_r0;
case 1:
return regs->ARM_r1;
case 2:
return regs->ARM_r2;
case 3:
return regs->ARM_r3;
}
return *((unsigned long *)regs->ARM_sp + n - 4);
}
static inline unsigned long swap_get_sarg(struct pt_regs *regs, unsigned long n)
{
return swap_get_karg(regs, n);
}
/* jumper */
typedef unsigned long (*jumper_cb_t)(void *);
unsigned long get_kjump_addr(void);
int set_kjump_cb(unsigned long ret_addr, struct pt_regs *regs,
jumper_cb_t cb, void *data, size_t size);
unsigned long get_jump_addr(void);
int set_jump_cb(unsigned long ret_addr, struct pt_regs *regs,
jumper_cb_t cb, void *data, size_t size);
int arch_init_kprobes(void);
void arch_exit_kprobes(void);
//void gen_insn_execbuf (void);
//void pc_dep_insn_execbuf (void);
//void gen_insn_execbuf_holder (void);
//void pc_dep_insn_execbuf_holder (void);
#endif /* _DBI_ASM_ARM_KPROBES_H */
|