diff options
Diffstat (limited to 'arch/x86/lib/insn-eval.c')
| -rw-r--r-- | arch/x86/lib/insn-eval.c | 71 | 
1 files changed, 47 insertions, 24 deletions
diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c index 53e57ef5925c..b781d324211b 100644 --- a/arch/x86/lib/insn-eval.c +++ b/arch/x86/lib/insn-eval.c @@ -410,32 +410,44 @@ static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx)  #endif /* CONFIG_X86_64 */  } -static int get_reg_offset(struct insn *insn, struct pt_regs *regs, -			  enum reg_type type) +static const int pt_regoff[] = { +	offsetof(struct pt_regs, ax), +	offsetof(struct pt_regs, cx), +	offsetof(struct pt_regs, dx), +	offsetof(struct pt_regs, bx), +	offsetof(struct pt_regs, sp), +	offsetof(struct pt_regs, bp), +	offsetof(struct pt_regs, si), +	offsetof(struct pt_regs, di), +#ifdef CONFIG_X86_64 +	offsetof(struct pt_regs, r8), +	offsetof(struct pt_regs, r9), +	offsetof(struct pt_regs, r10), +	offsetof(struct pt_regs, r11), +	offsetof(struct pt_regs, r12), +	offsetof(struct pt_regs, r13), +	offsetof(struct pt_regs, r14), +	offsetof(struct pt_regs, r15), +#else +	offsetof(struct pt_regs, ds), +	offsetof(struct pt_regs, es), +	offsetof(struct pt_regs, fs), +	offsetof(struct pt_regs, gs), +#endif +}; + +int pt_regs_offset(struct pt_regs *regs, int regno) +{ +	if ((unsigned)regno < ARRAY_SIZE(pt_regoff)) +		return pt_regoff[regno]; +	return -EDOM; +} + +static int get_regno(struct insn *insn, enum reg_type type)  { +	int nr_registers = ARRAY_SIZE(pt_regoff);  	int regno = 0; -	static const int regoff[] = { -		offsetof(struct pt_regs, ax), -		offsetof(struct pt_regs, cx), -		offsetof(struct pt_regs, dx), -		offsetof(struct pt_regs, bx), -		offsetof(struct pt_regs, sp), -		offsetof(struct pt_regs, bp), -		offsetof(struct pt_regs, si), -		offsetof(struct pt_regs, di), -#ifdef CONFIG_X86_64 -		offsetof(struct pt_regs, r8), -		offsetof(struct pt_regs, r9), -		offsetof(struct pt_regs, r10), -		offsetof(struct pt_regs, r11), -		offsetof(struct pt_regs, r12), -		offsetof(struct pt_regs, r13), -		offsetof(struct pt_regs, r14), -		offsetof(struct pt_regs, r15), -#endif -	}; -	int nr_registers = ARRAY_SIZE(regoff);  	/*  	 * Don't possibly decode a 32-bit instructions as  	 * reading a 64-bit-only register. @@ -503,7 +515,18 @@ static int get_reg_offset(struct insn *insn, struct pt_regs *regs,  		WARN_ONCE(1, "decoded an instruction with an invalid register");  		return -EINVAL;  	} -	return regoff[regno]; +	return regno; +} + +static int get_reg_offset(struct insn *insn, struct pt_regs *regs, +			  enum reg_type type) +{ +	int regno = get_regno(insn, type); + +	if (regno < 0) +		return regno; + +	return pt_regs_offset(regs, regno);  }  /**  | 
