Convert the function insn_get_add_ref into a wrapper function that calls the correct static address-decoding function depending on the size of the address. In this way, callers do not need to worry about calling the correct function and decreases the number of functions that need to be exposed. To this end, the original 32/64-bit insn_get_addr_ref is renamed as insn_get_addr_ref_32_64 to reflect the type of address encodings that it handles. Documentation is added to the new wrapper function and the documentation for the 32/64-bit address decoding function is improved. Cc: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx> Cc: Adam Buchbinder <adam.buchbinder@xxxxxxxxx> Cc: Colin Ian King <colin.king@xxxxxxxxxxxxx> Cc: Lorenzo Stoakes <lstoakes@xxxxxxxxx> Cc: Qiaowei Ren <qiaowei.ren@xxxxxxxxx> Cc: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> Cc: Masami Hiramatsu <mhiramat@xxxxxxxxxx> Cc: Adrian Hunter <adrian.hunter@xxxxxxxxx> Cc: Kees Cook <keescook@xxxxxxxxxxxx> Cc: Thomas Garnier <thgarnie@xxxxxxxxxx> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Cc: Borislav Petkov <bp@xxxxxxx> Cc: Dmitry Vyukov <dvyukov@xxxxxxxxxx> Cc: Ravi V. Shankar <ravi.v.shankar@xxxxxxxxx> Cc: x86@xxxxxxxxxx Signed-off-by: Ricardo Neri <ricardo.neri-calderon@xxxxxxxxxxxxxxx> --- arch/x86/lib/insn-eval.c | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c index cb1076d..e633588 100644 --- a/arch/x86/lib/insn-eval.c +++ b/arch/x86/lib/insn-eval.c @@ -705,12 +705,21 @@ static inline long __to_signed_long(unsigned long val, int long_bytes) #endif } -/* - * return the address being referenced be instruction - * for rm=3 returning the content of the rm reg - * for rm!=3 calculates the address using SIB and Disp +/** + * insn_get_addr_ref_32_64 - Obtain a 32/64-bit address referred by instruction + * @insn: Instruction struct with ModRM and SiB bytes and displacement + * @regs: Set of registers referred by the instruction + * + * This function is to be used with 32-bit and 64-bit address encodings. Obtain + * the memory address referred by the instruction's ModRM bytes and + * displacement. Also, the segment used as base is determined by either any + * segment override prefixes in insn or the default segment of the registers + * involved in the linear address computation. + * + * Return: linear address referenced by instruction and registers */ -void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) +static void __user *insn_get_addr_ref_32_64(struct insn *insn, + struct pt_regs *regs) { unsigned long linear_addr, seg_base_addr; long eff_addr, base, indx, tmp; @@ -795,3 +804,29 @@ void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) out_err: return (void __user *)-1; } + +/** + * insn_get_addr_ref - Obtain the linear address referred by instruction + * @insn: Instruction structure containing ModRM byte and displacement + * @regs: Set of registers referred by the instruction + * + * Obtain the memory address referred by the instruction's ModRM bytes and + * displacement. Also, the segment used as base is determined by either any + * segment override prefixes in insn or the default segment of the registers + * involved in the address computation. + * + * Return: linear address referenced by instruction and registers + */ +void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) +{ + switch (insn->addr_bytes) { + case 2: + return insn_get_addr_ref_16(insn, regs); + case 4: + /* fall through */ + case 8: + return insn_get_addr_ref_32_64(insn, regs); + default: + return (void __user *)-1; + } +} -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-msdos" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html