0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/types.h>
0010 #include <linux/kprobes.h>
0011 #include <linux/slab.h>
0012 #include <linux/uaccess.h>
0013 #include <asm/disasm.h>
0014
0015 #if defined(CONFIG_KGDB) || defined(CONFIG_ARC_EMUL_UNALIGNED) || \
0016 defined(CONFIG_KPROBES)
0017
0018
0019
0020
0021 void __kprobes disasm_instr(unsigned long addr, struct disasm_state *state,
0022 int userspace, struct pt_regs *regs, struct callee_regs *cregs)
0023 {
0024 int fieldA = 0;
0025 int fieldC = 0, fieldCisReg = 0;
0026 uint16_t word1 = 0, word0 = 0;
0027 int subopcode, is_linked, op_format;
0028 uint16_t *ins_ptr;
0029 uint16_t ins_buf[4];
0030 int bytes_not_copied = 0;
0031
0032 memset(state, 0, sizeof(struct disasm_state));
0033
0034
0035
0036 if (userspace) {
0037 bytes_not_copied = copy_from_user(ins_buf,
0038 (const void __user *) addr, 8);
0039 if (bytes_not_copied > 6)
0040 goto fault;
0041 ins_ptr = ins_buf;
0042 } else {
0043 ins_ptr = (uint16_t *) addr;
0044 }
0045
0046 word1 = *((uint16_t *)addr);
0047
0048 state->major_opcode = (word1 >> 11) & 0x1F;
0049
0050
0051 if (state->major_opcode < 0x0B) {
0052 if (bytes_not_copied > 4)
0053 goto fault;
0054 state->instr_len = 4;
0055 word0 = *((uint16_t *)(addr+2));
0056 state->words[0] = (word1 << 16) | word0;
0057 } else {
0058 state->instr_len = 2;
0059 state->words[0] = word1;
0060 }
0061
0062
0063 word1 = *((uint16_t *)(addr + state->instr_len));
0064 word0 = *((uint16_t *)(addr + state->instr_len + 2));
0065 state->words[1] = (word1 << 16) | word0;
0066
0067 switch (state->major_opcode) {
0068 case op_Bcc:
0069 state->is_branch = 1;
0070
0071
0072 fieldA = (IS_BIT(state->words[0], 16)) ?
0073 FIELD_s25(state->words[0]) :
0074 FIELD_s21(state->words[0]);
0075
0076 state->delay_slot = IS_BIT(state->words[0], 5);
0077 state->target = fieldA + (addr & ~0x3);
0078 state->flow = direct_jump;
0079 break;
0080
0081 case op_BLcc:
0082 if (IS_BIT(state->words[0], 16)) {
0083
0084
0085 fieldA = (IS_BIT(state->words[0], 17)) ?
0086 (FIELD_s25(state->words[0]) & ~0x3) :
0087 FIELD_s21(state->words[0]);
0088
0089 state->flow = direct_call;
0090 } else {
0091
0092 fieldA = FIELD_s9(state->words[0]) & ~0x3;
0093 state->flow = direct_jump;
0094 }
0095
0096 state->delay_slot = IS_BIT(state->words[0], 5);
0097 state->target = fieldA + (addr & ~0x3);
0098 state->is_branch = 1;
0099 break;
0100
0101 case op_LD:
0102 state->write = 0;
0103 state->di = BITS(state->words[0], 11, 11);
0104 if (state->di)
0105 break;
0106 state->x = BITS(state->words[0], 6, 6);
0107 state->zz = BITS(state->words[0], 7, 8);
0108 state->aa = BITS(state->words[0], 9, 10);
0109 state->wb_reg = FIELD_B(state->words[0]);
0110 if (state->wb_reg == REG_LIMM) {
0111 state->instr_len += 4;
0112 state->aa = 0;
0113 state->src1 = state->words[1];
0114 } else {
0115 state->src1 = get_reg(state->wb_reg, regs, cregs);
0116 }
0117 state->src2 = FIELD_s9(state->words[0]);
0118 state->dest = FIELD_A(state->words[0]);
0119 state->pref = (state->dest == REG_LIMM);
0120 break;
0121
0122 case op_ST:
0123 state->write = 1;
0124 state->di = BITS(state->words[0], 5, 5);
0125 if (state->di)
0126 break;
0127 state->aa = BITS(state->words[0], 3, 4);
0128 state->zz = BITS(state->words[0], 1, 2);
0129 state->src1 = FIELD_C(state->words[0]);
0130 if (state->src1 == REG_LIMM) {
0131 state->instr_len += 4;
0132 state->src1 = state->words[1];
0133 } else {
0134 state->src1 = get_reg(state->src1, regs, cregs);
0135 }
0136 state->wb_reg = FIELD_B(state->words[0]);
0137 if (state->wb_reg == REG_LIMM) {
0138 state->aa = 0;
0139 state->instr_len += 4;
0140 state->src2 = state->words[1];
0141 } else {
0142 state->src2 = get_reg(state->wb_reg, regs, cregs);
0143 }
0144 state->src3 = FIELD_s9(state->words[0]);
0145 break;
0146
0147 case op_MAJOR_4:
0148 subopcode = MINOR_OPCODE(state->words[0]);
0149 switch (subopcode) {
0150 case 32:
0151 case 33:
0152 case 34:
0153 case 35:
0154 is_linked = 0;
0155
0156 if (subopcode == 33 || subopcode == 35)
0157 state->delay_slot = 1;
0158
0159 if (subopcode == 34 || subopcode == 35)
0160 is_linked = 1;
0161
0162 fieldCisReg = 0;
0163 op_format = BITS(state->words[0], 22, 23);
0164 if (op_format == 0 || ((op_format == 3) &&
0165 (!IS_BIT(state->words[0], 5)))) {
0166 fieldC = FIELD_C(state->words[0]);
0167
0168 if (fieldC == REG_LIMM) {
0169 fieldC = state->words[1];
0170 state->instr_len += 4;
0171 } else {
0172 fieldCisReg = 1;
0173 }
0174 } else if (op_format == 1 || ((op_format == 3)
0175 && (IS_BIT(state->words[0], 5)))) {
0176 fieldC = FIELD_C(state->words[0]);
0177 } else {
0178
0179 fieldC = FIELD_s12(state->words[0]);
0180 }
0181
0182 if (!fieldCisReg) {
0183 state->target = fieldC;
0184 state->flow = is_linked ?
0185 direct_call : direct_jump;
0186 } else {
0187 state->target = get_reg(fieldC, regs, cregs);
0188 state->flow = is_linked ?
0189 indirect_call : indirect_jump;
0190 }
0191 state->is_branch = 1;
0192 break;
0193
0194 case 40:
0195 if (BITS(state->words[0], 22, 23) == 3) {
0196
0197 fieldC = FIELD_C(state->words[0]);
0198
0199 fieldC = fieldC << 1;
0200 fieldC += (addr & ~0x03);
0201 state->is_branch = 1;
0202 state->flow = direct_jump;
0203 state->target = fieldC;
0204 }
0205
0206
0207 break;
0208
0209 case 48 ... 55:
0210 state->di = BITS(state->words[0], 15, 15);
0211 if (state->di)
0212 break;
0213 state->x = BITS(state->words[0], 16, 16);
0214 state->zz = BITS(state->words[0], 17, 18);
0215 state->aa = BITS(state->words[0], 22, 23);
0216 state->wb_reg = FIELD_B(state->words[0]);
0217 if (state->wb_reg == REG_LIMM) {
0218 state->instr_len += 4;
0219 state->src1 = state->words[1];
0220 } else {
0221 state->src1 = get_reg(state->wb_reg, regs,
0222 cregs);
0223 }
0224 state->src2 = FIELD_C(state->words[0]);
0225 if (state->src2 == REG_LIMM) {
0226 state->instr_len += 4;
0227 state->src2 = state->words[1];
0228 } else {
0229 state->src2 = get_reg(state->src2, regs,
0230 cregs);
0231 }
0232 state->dest = FIELD_A(state->words[0]);
0233 if (state->dest == REG_LIMM)
0234 state->pref = 1;
0235 break;
0236
0237 case 10:
0238
0239
0240 switch (BITS(state->words[0], 22, 23)) {
0241 case 0:
0242 if (FIELD_C(state->words[0]) == REG_LIMM)
0243 state->instr_len += 4;
0244 break;
0245 case 1:
0246 break;
0247 case 2:
0248 break;
0249 case 3:
0250 if ((!IS_BIT(state->words[0], 5)) &&
0251 (FIELD_C(state->words[0]) == REG_LIMM))
0252 state->instr_len += 4;
0253 break;
0254 }
0255 break;
0256
0257
0258 default:
0259
0260
0261 switch (BITS(state->words[0], 22, 23)) {
0262 case 0:
0263 if ((FIELD_B(state->words[0]) == REG_LIMM) ||
0264 (FIELD_C(state->words[0]) == REG_LIMM))
0265 state->instr_len += 4;
0266 break;
0267 case 1:
0268 break;
0269 case 2:
0270 break;
0271 case 3:
0272 if ((!IS_BIT(state->words[0], 5)) &&
0273 ((FIELD_B(state->words[0]) == REG_LIMM) ||
0274 (FIELD_C(state->words[0]) == REG_LIMM)))
0275 state->instr_len += 4;
0276 break;
0277 }
0278 break;
0279 }
0280 break;
0281
0282
0283 case op_LD_ADD:
0284 state->zz = BITS(state->words[0], 3, 4);
0285 state->src1 = get_reg(FIELD_S_B(state->words[0]), regs, cregs);
0286 state->src2 = get_reg(FIELD_S_C(state->words[0]), regs, cregs);
0287 state->dest = FIELD_S_A(state->words[0]);
0288 break;
0289
0290 case op_ADD_MOV_CMP:
0291
0292 if ((BITS(state->words[0], 3, 4) < 3) &&
0293 (FIELD_S_H(state->words[0]) == REG_LIMM))
0294 state->instr_len += 4;
0295 break;
0296
0297 case op_S:
0298 subopcode = BITS(state->words[0], 5, 7);
0299 switch (subopcode) {
0300 case 0:
0301 case 1:
0302 case 2:
0303 case 3:
0304 state->target = get_reg(FIELD_S_B(state->words[0]),
0305 regs, cregs);
0306 state->delay_slot = subopcode & 1;
0307 state->flow = (subopcode >= 2) ?
0308 direct_call : indirect_jump;
0309 break;
0310 case 7:
0311 switch (BITS(state->words[0], 8, 10)) {
0312 case 4:
0313 case 5:
0314 case 6:
0315 case 7:
0316 state->delay_slot = (subopcode == 7);
0317 state->flow = indirect_jump;
0318 state->target = get_reg(31, regs, cregs);
0319 default:
0320 break;
0321 }
0322 default:
0323 break;
0324 }
0325 break;
0326
0327 case op_LD_S:
0328 state->src1 = get_reg(FIELD_S_B(state->words[0]), regs, cregs);
0329 state->src2 = FIELD_S_u7(state->words[0]);
0330 state->dest = FIELD_S_C(state->words[0]);
0331 break;
0332
0333 case op_LDB_S:
0334 case op_STB_S:
0335
0336
0337 state->zz = 1;
0338 break;
0339
0340 case op_LDWX_S:
0341 state->x = 1;
0342 fallthrough;
0343
0344 case op_LDW_S:
0345 state->zz = 2;
0346 state->src1 = get_reg(FIELD_S_B(state->words[0]), regs, cregs);
0347 state->src2 = FIELD_S_u6(state->words[0]);
0348 state->dest = FIELD_S_C(state->words[0]);
0349 break;
0350
0351 case op_ST_S:
0352 state->write = 1;
0353 state->src1 = get_reg(FIELD_S_C(state->words[0]), regs, cregs);
0354 state->src2 = get_reg(FIELD_S_B(state->words[0]), regs, cregs);
0355 state->src3 = FIELD_S_u7(state->words[0]);
0356 break;
0357
0358 case op_STW_S:
0359 state->write = 1;
0360 state->zz = 2;
0361 state->src1 = get_reg(FIELD_S_C(state->words[0]), regs, cregs);
0362 state->src2 = get_reg(FIELD_S_B(state->words[0]), regs, cregs);
0363 state->src3 = FIELD_S_u6(state->words[0]);
0364 break;
0365
0366 case op_SP:
0367
0368
0369
0370 state->write = BITS(state->words[0], 6, 6);
0371 state->zz = BITS(state->words[0], 5, 5);
0372 if (state->zz)
0373 break;
0374 if (!state->write) {
0375 state->src1 = get_reg(28, regs, cregs);
0376 state->src2 = FIELD_S_u7(state->words[0]);
0377 state->dest = FIELD_S_B(state->words[0]);
0378 } else {
0379 state->src1 = get_reg(FIELD_S_B(state->words[0]), regs,
0380 cregs);
0381 state->src2 = get_reg(28, regs, cregs);
0382 state->src3 = FIELD_S_u7(state->words[0]);
0383 }
0384 break;
0385
0386 case op_GP:
0387
0388 state->zz = BITS(state->words[0], 9, 10);
0389 state->src1 = get_reg(26, regs, cregs);
0390 state->src2 = state->zz ? FIELD_S_s10(state->words[0]) :
0391 FIELD_S_s11(state->words[0]);
0392 state->dest = 0;
0393 break;
0394
0395 case op_Pcl:
0396 state->src1 = regs->ret & ~3;
0397 state->src2 = FIELD_S_u10(state->words[0]);
0398 state->dest = FIELD_S_B(state->words[0]);
0399 break;
0400
0401 case op_BR_S:
0402 state->target = FIELD_S_s8(state->words[0]) + (addr & ~0x03);
0403 state->flow = direct_jump;
0404 state->is_branch = 1;
0405 break;
0406
0407 case op_B_S:
0408 fieldA = (BITS(state->words[0], 9, 10) == 3) ?
0409 FIELD_S_s7(state->words[0]) :
0410 FIELD_S_s10(state->words[0]);
0411 state->target = fieldA + (addr & ~0x03);
0412 state->flow = direct_jump;
0413 state->is_branch = 1;
0414 break;
0415
0416 case op_BL_S:
0417 state->target = FIELD_S_s13(state->words[0]) + (addr & ~0x03);
0418 state->flow = direct_call;
0419 state->is_branch = 1;
0420 break;
0421
0422 default:
0423 break;
0424 }
0425
0426 if (bytes_not_copied <= (8 - state->instr_len))
0427 return;
0428
0429 fault: state->fault = 1;
0430 }
0431
0432 long __kprobes get_reg(int reg, struct pt_regs *regs,
0433 struct callee_regs *cregs)
0434 {
0435 long *p;
0436
0437 #if defined(CONFIG_ISA_ARCOMPACT)
0438 if (reg <= 12) {
0439 p = ®s->r0;
0440 return p[-reg];
0441 }
0442 #else
0443 if (reg <= 11) {
0444 p = ®s->r0;
0445 return p[reg];
0446 }
0447
0448 if (reg == 12)
0449 return regs->r12;
0450 if (reg == 30)
0451 return regs->r30;
0452 #ifdef CONFIG_ARC_HAS_ACCL_REGS
0453 if (reg == 58)
0454 return regs->r58;
0455 if (reg == 59)
0456 return regs->r59;
0457 #endif
0458 #endif
0459 if (cregs && (reg <= 25)) {
0460 p = &cregs->r13;
0461 return p[13 - reg];
0462 }
0463
0464 if (reg == 26)
0465 return regs->r26;
0466 if (reg == 27)
0467 return regs->fp;
0468 if (reg == 28)
0469 return regs->sp;
0470 if (reg == 31)
0471 return regs->blink;
0472
0473 return 0;
0474 }
0475
0476 void __kprobes set_reg(int reg, long val, struct pt_regs *regs,
0477 struct callee_regs *cregs)
0478 {
0479 long *p;
0480
0481 #if defined(CONFIG_ISA_ARCOMPACT)
0482 switch (reg) {
0483 case 0 ... 12:
0484 p = ®s->r0;
0485 p[-reg] = val;
0486 break;
0487 case 13 ... 25:
0488 if (cregs) {
0489 p = &cregs->r13;
0490 p[13 - reg] = val;
0491 }
0492 break;
0493 case 26:
0494 regs->r26 = val;
0495 break;
0496 case 27:
0497 regs->fp = val;
0498 break;
0499 case 28:
0500 regs->sp = val;
0501 break;
0502 case 31:
0503 regs->blink = val;
0504 break;
0505 default:
0506 break;
0507 }
0508 #else
0509 switch (reg) {
0510 case 0 ... 11:
0511 p = ®s->r0;
0512 p[reg] = val;
0513 break;
0514 case 12:
0515 regs->r12 = val;
0516 break;
0517 case 13 ... 25:
0518 if (cregs) {
0519 p = &cregs->r13;
0520 p[13 - reg] = val;
0521 }
0522 break;
0523 case 26:
0524 regs->r26 = val;
0525 break;
0526 case 27:
0527 regs->fp = val;
0528 break;
0529 case 28:
0530 regs->sp = val;
0531 break;
0532 case 30:
0533 regs->r30 = val;
0534 break;
0535 case 31:
0536 regs->blink = val;
0537 break;
0538 #ifdef CONFIG_ARC_HAS_ACCL_REGS
0539 case 58:
0540 regs->r58 = val;
0541 break;
0542 case 59:
0543 regs->r59 = val;
0544 break;
0545 #endif
0546 default:
0547 break;
0548 }
0549 #endif
0550 }
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560 int __kprobes disasm_next_pc(unsigned long pc, struct pt_regs *regs,
0561 struct callee_regs *cregs,
0562 unsigned long *next_pc, unsigned long *tgt_if_br)
0563 {
0564 struct disasm_state instr;
0565
0566 disasm_instr(pc, &instr, 0, regs, cregs);
0567
0568 *next_pc = pc + instr.instr_len;
0569
0570
0571 if (instr.is_branch)
0572 *tgt_if_br = instr.target;
0573
0574
0575
0576
0577 if (instr.delay_slot) {
0578 struct disasm_state instr_d;
0579
0580 disasm_instr(*next_pc, &instr_d, 0, regs, cregs);
0581
0582 *next_pc += instr_d.instr_len;
0583 }
0584
0585
0586 if (!(regs->status32 & STATUS32_L) && (*next_pc == regs->lp_end)
0587 && (regs->lp_count > 1)) {
0588 *next_pc = regs->lp_start;
0589 }
0590
0591 return instr.is_branch;
0592 }
0593
0594 #endif