From 958465ee5407dc1b25ba6eb33f0e8bb6179960ee Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 30 Aug 2017 14:12:31 +1000 Subject: powerpc: Add emulation for the addpcis instruction The addpcis instruction puts the sum of the next instruction address plus a constant into a register. Since the result depends on the address of the instruction, it will give an incorrect result if it is single-stepped out of line, which is what the *probes subsystem will currently do if a probe is placed on an addpcis instruction. This fixes the problem by adding emulation of it to analyse_instr(). Signed-off-by: Paul Mackerras Signed-off-by: Michael Ellerman --- arch/powerpc/lib/sstep.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'arch/powerpc/lib') diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 10eabd9a255d..96283499664b 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -1021,9 +1021,6 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->ccval = (regs->ccr & ~(1UL << (31 - rd))) | (val << (31 - rd)); return 1; - default: - op->type = UNKNOWN; - return 0; } break; case 31: @@ -1123,6 +1120,17 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->val = imm; goto compute_done; + case 19: + if (((instr >> 1) & 0x1f) == 2) { + /* addpcis */ + imm = (short) (instr & 0xffc1); /* d0 + d2 fields */ + imm |= (instr >> 15) & 0x3e; /* d1 field */ + op->val = regs->nip + (imm << 16) + 4; + goto compute_done; + } + op->type = UNKNOWN; + return 0; + case 20: /* rlwimi */ mb = (instr >> 6) & 0x1f; me = (instr >> 1) & 0x1f; -- cgit