Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RzIL for floating-point x86 instructions #3865

Merged
merged 55 commits into from
Feb 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
d944a9b
Create `il_fp_ops.inc`, for floating-point instructions' IL ops
DMaroo Sep 15, 2023
70e3393
Add IL implementation for `FABS`
DMaroo Sep 16, 2023
d4a7140
Add IL implementation for `FNINIT` and `FLDCW`
DMaroo Sep 17, 2023
48f8e7c
Add IL implementations for `FNSTCW` and `FNSTSW`
DMaroo Sep 17, 2023
0136ec5
Add IL implementation for `FNCLEX`
DMaroo Sep 17, 2023
aa75db8
Add ST push and pop functions
DMaroo Oct 23, 2023
4d3b611
Fix clang formatting
DMaroo Oct 23, 2023
28f8b0e
Add fucntions for updating FPSW TOP pointer
DMaroo Oct 25, 2023
8623879
Add `FLD` instruction lifitng, FPSW flag support, FP operand support
DMaroo Oct 25, 2023
1231de2
Remove `x86_bool_to_bv` and use the standard `BOOL_TO_BV`
DMaroo Oct 25, 2023
551026c
Add implementation for `FST{P}`, and rounding mode support
DMaroo Oct 25, 2023
d117bbd
Add `FLD` variants for constants
DMaroo Oct 25, 2023
e585599
Fix formatting and build
DMaroo Oct 25, 2023
94b2c41
Add IL lifting for `FXCH`
DMaroo Oct 25, 2023
58c5867
Add width checks to avoid redundant rounding
DMaroo Oct 27, 2023
8ff111a
Implement IL lifting for `FILD`, `FIST{P}`
DMaroo Oct 29, 2023
8401866
FPU stack regs are 80-bit, not 64-bit
DMaroo Oct 29, 2023
6941e80
Add RzIL lifting for `FBLD`
DMaroo Dec 16, 2023
8b92c07
Add RzIL implementation for `FBSTP`
DMaroo Dec 17, 2023
1d61298
Remove all the `EMPTY()` ops after `GOTO()` ops
DMaroo Dec 17, 2023
65192da
Moved some code around
DMaroo Dec 17, 2023
a290416
Rename "rmode" local variable to "_rmode"
DMaroo Dec 21, 2023
de47298
Add some TODOs for deffered work
DMaroo Dec 23, 2023
232584a
Fix failing asm tests
DMaroo Dec 23, 2023
f31dc92
Implement IL lifting for `FADD` (and some other minor refactoring)
DMaroo Dec 24, 2023
cff71b4
Use a global to denote when RMode needs to be init, implement FIADD
DMaroo Dec 25, 2023
4e86b04
Implement `FMUL` and `FIMUL`
DMaroo Dec 26, 2023
0e1a3d7
Implement RzIL for `FSUB` and `FISUB`
DMaroo Jan 1, 2024
bfab55a
Implement RzIL for `FSUBR` and `FISUBR`
DMaroo Jan 1, 2024
744fd47
Add RzIL implementation for `FDIV`, `FIDIV`, `FDIVR`, `FIDIVR`
DMaroo Jan 1, 2024
23c1965
Add pop versions of floating point arithmetic instuctions
DMaroo Jan 1, 2024
753c35d
Add RzIL implementations for `FCOM`, `FCOMP` and `FCOMPP`
DMaroo Jan 1, 2024
fc861d9
Add RzIL lifting for `FUCOM` and `FCOMI` families of instructions
DMaroo Jan 1, 2024
888056c
Implement RzIL lifting for `FCHS` and `FTST`
DMaroo Jan 1, 2024
51965ee
Add RzIL implementation for `FRNDINT` and `FSQRT`
DMaroo Jan 1, 2024
d0c98e2
Add RzIL implementation for `FNOP` and `FISTTP`
DMaroo Jan 1, 2024
7f7d9a9
Remove global variable `use_rmode` and use pass around a context instead
DMaroo Jan 2, 2024
2a6d566
Add RzIL for `FICOM` and `FICOMP`, add register bindings and fix bugs
DMaroo Jan 2, 2024
b87c768
Make `rz-test` more robust against IL outputs with newlines in them
DMaroo Jan 2, 2024
bcead9f
Add RzIL tests in db/asm for x86 FPU instructions
DMaroo Jan 2, 2024
1f8e4ff
Fix the bug when using `FADDP` with Capstone version > 4
DMaroo Jan 2, 2024
e84d490
Fix remaining db tests
DMaroo Jan 2, 2024
9061b13
Remove tests for `FSTSW` or `FSTCW` instructions
DMaroo Jan 3, 2024
d0a53da
Add asm tests for math constant push instructions
DMaroo Jan 4, 2024
2904923
Add `RZ_IPI` annotation for all the functions exposed through the header
DMaroo Jan 8, 2024
cb4f92d
Add `RZ_OWN`, `RZ_BORROW` and `RZ_NONNULL` annotations
DMaroo Jan 8, 2024
75e2c3c
Add Doxygen doc for `ctx` argument
DMaroo Jan 8, 2024
ae94780
Add description for the `EXEC_WITH_RMODE` macro
DMaroo Jan 11, 2024
5108da2
Move the non-null check for `ctx` inside the valid branch
DMaroo Jan 11, 2024
436077f
Minor bug fixes + make the annotations less strict than they need to be
DMaroo Jan 11, 2024
921618d
Minor bug fixes
DMaroo Jan 15, 2024
8e5cf1d
Fix asm tests for `JMP` and `RET` instructions
DMaroo Jan 15, 2024
0a4aa7b
Fix indexing error for `FXCH`
DMaroo Feb 17, 2024
9318e02
Review changes
DMaroo Feb 17, 2024
0516511
Merge branch 'dev' into x86-il-floating-point
XVilka Feb 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
573 changes: 533 additions & 40 deletions librz/analysis/arch/x86/common.c

Large diffs are not rendered by default.

120 changes: 105 additions & 15 deletions librz/analysis/arch/x86/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#define X86_BIT(x) UN(1, x)
#define X86_TO32(x) UNSIGNED(32, x)

#define IL_LIFTER(mnem) static RzILOpEffect *x86_il_##mnem(const X86ILIns *ins, ut64 pc, RzAnalysis *analysis)
#define IL_LIFTER(mnem) static RzILOpEffect *x86_il_##mnem(const X86ILIns *ins, ut64 pc, RzAnalysis *analysis, X86ILContext *ctx)

// Namespace clash with android-ndk-25b's x86_64-linux-android/asm/processor-flags.h
#undef X86_EFLAGS_CF
Expand Down Expand Up @@ -84,24 +84,114 @@ typedef enum x86_eflags_t {

extern const char *x86_eflags_registers[X86_EFLAGS_ENDING];

RzILOpPure *x86_il_get_reg_bits(X86Reg reg, int bits, uint64_t pc);
RzILOpEffect *x86_il_set_reg_bits(X86Reg reg, RzILOpPure *val, int bits);
RZ_IPI RzILOpPure *x86_il_get_reg_bits(X86Reg reg, int bits, uint64_t pc);
RZ_IPI RzILOpEffect *x86_il_set_reg_bits(X86Reg reg, RZ_OWN RZ_NONNULL RzILOpPure *val, int bits);

RzILOpPure *x86_il_get_operand_bits(X86Op op, int analysis_bits, ut64 pc, int implicit_size);
RzILOpEffect *x86_il_set_operand_bits(X86Op op, RzILOpPure *val, int bits, ut64 pc);
RZ_IPI RzILOpPure *x86_il_get_operand_bits(X86Op op, int analysis_bits, ut64 pc, int implicit_size);
RZ_IPI RzILOpEffect *x86_il_set_operand_bits(X86Op op, RZ_OWN RZ_NONNULL RzILOpPure *val, int bits, ut64 pc);

RzILOpPure *x86_il_get_memaddr_bits(X86Mem mem, int bits, ut64 pc);
RzILOpPure *x86_il_get_memaddr_segment_bits(X86Mem mem, X86Reg segment, int bits, ut64 pc);
RzILOpEffect *x86_il_set_mem_bits(X86Mem mem, RzILOpPure *val, int bits, ut64 pc);
RZ_IPI RzILOpPure *x86_il_get_memaddr_bits(X86Mem mem, int bits, ut64 pc);
RZ_IPI RzILOpPure *x86_il_get_memaddr_segment_bits(X86Mem mem, X86Reg segment, int bits, ut64 pc);
RZ_IPI RzILOpEffect *x86_il_set_mem_bits(X86Mem mem, RZ_OWN RZ_NONNULL RzILOpPure *val, int bits, ut64 pc);

RzILOpBool *x86_il_is_sub_borrow(RZ_OWN RzILOpPure *res, RZ_OWN RzILOpPure *x, RZ_OWN RzILOpPure *y);
RzILOpBitVector *x86_bool_to_bv(RzILOpBool *b, unsigned int bits);
RZ_IPI RzILOpBool *x86_il_is_add_carry(RZ_OWN RZ_NONNULL RzILOpPure *res, RZ_OWN RZ_NONNULL RzILOpPure *x, RZ_OWN RZ_NONNULL RzILOpPure *y);
RZ_IPI RzILOpBool *x86_il_is_sub_borrow(RZ_OWN RZ_NONNULL RzILOpPure *res, RZ_OWN RZ_NONNULL RzILOpPure *x, RZ_OWN RZ_NONNULL RzILOpPure *y);
RZ_IPI RzILOpBool *x86_il_is_add_overflow(RZ_OWN RZ_NONNULL RzILOpPure *res, RZ_OWN RZ_NONNULL RzILOpPure *x, RZ_OWN RZ_NONNULL RzILOpPure *y);
RZ_IPI RzILOpBool *x86_il_is_sub_underflow(RZ_OWN RZ_NONNULL RzILOpPure *res, RZ_OWN RZ_NONNULL RzILOpPure *x, RZ_OWN RZ_NONNULL RzILOpPure *y);

RzILOpEffect *x86_il_set_result_flags_bits(RZ_OWN RzILOpPure *result, int bits);
RzILOpEffect *x86_il_set_arithmetic_flags_bits(RZ_OWN RzILOpPure *res, RZ_OWN RzILOpPure *x, RZ_OWN RzILOpPure *y, bool addition, int bits);
RzILOpEffect *x86_il_set_arithmetic_flags_except_cf_bits(RZ_OWN RzILOpPure *res, RZ_OWN RzILOpPure *x, RZ_OWN RzILOpPure *y, bool addition, int bits);
RZ_IPI RzILOpEffect *x86_il_set_result_flags_bits(RZ_OWN RZ_NONNULL RzILOpPure *result, int bits);
RZ_IPI RzILOpEffect *x86_il_set_arithmetic_flags_bits(RZ_OWN RZ_NONNULL RzILOpPure *res, RZ_OWN RZ_NONNULL RzILOpPure *x, RZ_OWN RZ_NONNULL RzILOpPure *y, bool addition, int bits);
RZ_IPI RzILOpEffect *x86_il_set_arithmetic_flags_except_cf_bits(RZ_OWN RZ_NONNULL RzILOpPure *res, RZ_OWN RZ_NONNULL RzILOpPure *x, RZ_OWN RZ_NONNULL RzILOpPure *y, bool addition, int bits);

RzILOpPure *x86_il_get_flags(unsigned int size);
RzILOpEffect *x86_il_set_flags(RZ_OWN RzILOpPure *val, unsigned int size);
RZ_IPI RzILOpPure *x86_il_get_flags(unsigned int size);
RZ_IPI RzILOpEffect *x86_il_set_flags(RZ_OWN RZ_NONNULL RzILOpPure *val, unsigned int size);

/* Capstone does not have the following FPU registers. */

/* FPU control word */
#define X86_REG_FPU_CW "cwd"
/* FPU tag word */
#define X86_REG_FPU_TW "ftw"
/* FPU last instruction opcode */
#define X86_REG_FPU_OP "fop"
/* FPU instruction pointer */
#define X86_REG_FPU_IP "frip"
/* FPU data pointer */
#define X86_REG_FPU_DP "frdp"

typedef enum {
X86_FPU_C0 = 8,
X86_FPU_C1 = 9,
X86_FPU_C2 = 10,
X86_FPU_C3 = 14,
} X86FPUFlags;

RZ_IPI bool x86_il_is_st_reg(X86Reg reg);

/* Need to pass in val_size as a param to avoid unnecessary rounding of val. */

RZ_IPI RzILOpFloat *x86_il_get_st_reg(X86Reg reg);
RZ_IPI RzILOpEffect *x86_il_set_st_reg_ctx(X86Reg reg, RZ_OWN RZ_NONNULL RzILOpFloat *val, RzFloatFormat val_format, RZ_BORROW X86ILContext *ctx);

#define x86_il_set_st_reg(reg, val, val_format) x86_il_set_st_reg_ctx(reg, val, val_format, ctx)

RZ_IPI RzILOpEffect *x86_il_set_fpu_stack_top(RZ_OWN RZ_NONNULL RzILOpPure *top);
RZ_IPI RzILOpPure *x86_il_get_fpu_stack_top();

RZ_IPI RzILOpEffect *x86_il_st_push_ctx(RZ_OWN RZ_NONNULL RzILOpFloat *val, RzFloatFormat val_format, RZ_BORROW X86ILContext *ctx);
RZ_IPI RzILOpEffect *x86_il_st_pop();

#define x86_il_st_push(val, val_format) x86_il_st_push_ctx(val, val_format, ctx)

#define X86_IL_ST_POP(val, eff) \
do { \
val = x86_il_get_st_reg(X86_REG_ST0); \
eff = x86_il_st_pop(); \
} while (0)

RZ_IPI RzILOpPure *x86_il_get_fpu_flag(X86FPUFlags flag);
RZ_IPI RzILOpEffect *x86_il_set_fpu_flag(X86FPUFlags flag, RZ_OWN RZ_NONNULL RzILOpBool *value);

RZ_IPI RzILOpPure *x86_il_fpu_get_rmode();

RZ_IPI RzILOpEffect *init_rmode();

RZ_IPI RzILOpFloat *x86_il_resize_floating_ctx(RZ_OWN RZ_NONNULL RzILOpFloat *val, RzFloatFormat format, RZ_BORROW RZ_NONNULL X86ILContext *ctx);
RZ_IPI RzILOpFloat *x86_il_floating_from_int_ctx(RZ_OWN RZ_NONNULL RzILOpBitVector *int_val, RzFloatFormat format, RZ_BORROW RZ_NONNULL X86ILContext *ctx);
RZ_IPI RzILOpBitVector *x86_il_int_from_floating_ctx(RZ_OWN RZ_NONNULL RzILOpFloat *float_val, ut32 width, RZ_BORROW RZ_NONNULL X86ILContext *ctx);

RZ_IPI RzILOpFloat *x86_il_fadd_with_rmode_ctx(RZ_OWN RZ_NONNULL RzILOpFloat *x, RZ_OWN RZ_NONNULL RzILOpFloat *y, RZ_BORROW RZ_NONNULL X86ILContext *ctx);
RZ_IPI RzILOpFloat *x86_il_fmul_with_rmode_ctx(RZ_OWN RZ_NONNULL RzILOpFloat *x, RZ_OWN RZ_NONNULL RzILOpFloat *y, RZ_BORROW RZ_NONNULL X86ILContext *ctx);
RZ_IPI RzILOpFloat *x86_il_fsub_with_rmode_ctx(RZ_OWN RZ_NONNULL RzILOpFloat *x, RZ_OWN RZ_NONNULL RzILOpFloat *y, RZ_BORROW RZ_NONNULL X86ILContext *ctx);
RZ_IPI RzILOpFloat *x86_il_fsubr_with_rmode_ctx(RZ_OWN RZ_NONNULL RzILOpFloat *x, RZ_OWN RZ_NONNULL RzILOpFloat *y, RZ_BORROW RZ_NONNULL X86ILContext *ctx);
RZ_IPI RzILOpFloat *x86_il_fdiv_with_rmode_ctx(RZ_OWN RZ_NONNULL RzILOpFloat *x, RZ_OWN RZ_NONNULL RzILOpFloat *y, RZ_BORROW RZ_NONNULL X86ILContext *ctx);
RZ_IPI RzILOpFloat *x86_il_fdivr_with_rmode_ctx(RZ_OWN RZ_NONNULL RzILOpFloat *x, RZ_OWN RZ_NONNULL RzILOpFloat *y, RZ_BORROW RZ_NONNULL X86ILContext *ctx);
RZ_IPI RzILOpFloat *x86_il_fsqrt_with_rmode_ctx(RZ_OWN RZ_NONNULL RzILOpFloat *x, RZ_BORROW RZ_NONNULL X86ILContext *ctx);

#define x86_il_resize_floating(val, format) x86_il_resize_floating_ctx(val, format, ctx)
#define x86_il_floating_from_int(int_val, format) x86_il_floating_from_int_ctx(int_val, format, ctx)
#define x86_il_int_from_floating(float_val, width) x86_il_int_from_floating_ctx(float_val, width, ctx)
#define x86_il_fadd_with_rmode(x, y) x86_il_fadd_with_rmode_ctx(x, y, ctx)
#define x86_il_fmul_with_rmode(x, y) x86_il_fmul_with_rmode_ctx(x, y, ctx)
#define x86_il_fsub_with_rmode(x, y) x86_il_fsub_with_rmode_ctx(x, y, ctx)
#define x86_il_fsubr_with_rmode(x, y) x86_il_fsubr_with_rmode_ctx(x, y, ctx)
#define x86_il_fdiv_with_rmode(x, y) x86_il_fdiv_with_rmode_ctx(x, y, ctx)
#define x86_il_fdivr_with_rmode(x, y) x86_il_fdivr_with_rmode_ctx(x, y, ctx)
#define x86_il_fsqrt_with_rmode(x) x86_il_fsqrt_with_rmode_ctx(x, ctx)

RZ_IPI RzILOpPure *x86_il_get_floating_operand_bits(X86Op op, int analysis_bits, ut64 pc);

#define x86_il_get_floating_op(opnum) \
x86_il_get_floating_operand_bits(ins->structure->operands[opnum], analysis->bits, pc)

RZ_IPI RzFloatFormat x86_width_to_format(ut8 width);
RZ_IPI ut8 x86_format_to_width(RzFloatFormat format);

RZ_IPI RzILOpEffect *x86_il_set_floating_operand_bits_ctx(X86Op op, RZ_OWN RZ_NONNULL RzILOpFloat *val, RzFloatFormat val_format, int bits, ut64 pc, RZ_BORROW X86ILContext *ctx);

#define x86_il_set_floating_op(opnum, val, val_format) \
x86_il_set_floating_operand_bits_ctx(ins->structure->operands[opnum], val, val_format, analysis->bits, pc, ctx)

RZ_IPI RzILOpEffect *x86_il_clear_fpsw_flags();

#endif // X86_IL_COMMON_H
Loading
Loading