lifting-bits / remill

Library for lifting machine code to LLVM bitcode
Apache License 2.0
1.27k stars 143 forks source link

Semantics test failures on AMD Zen3 CPUs #471

Closed artemdinaburg closed 1 year ago

artemdinaburg commented 3 years ago

Some x86-64 semantics test fail on AMD Zen3 CPUs. An output log is attached. Detailed output:

F2XM1_1
FABS_1
FADDP_2
FADDPst1_2
FADDm32_2
FADDm64_2
FADDst1_2
FBLD_2
FBSTP_1
FCHS_1
FCMOVBE_1
FCMOVB_1
FCMOVE_1
FCMOVNBE_1
FCMOVNB_1
FCMOVNE_1
FCMOVNU_1
FCMOVU_1
FCOMIPst0st2_2
FCOMIst0st2_2
FCOMPPst0st1_2
FCOMPst0st1_2
FCOMPst0st2_2
FCOMst0st1_2
FCOMst0st2_2
FCOS_1
FDECSTP_1
FDIVP_2
FDIVPst1_2
FDIVRP_2
FDIVRPst1_2
FDIVRm32_2
FDIVRm64_2
FDIVRst1_2
FDIVm32_2
FDIVm64_2
FDIVst1_2
FFREEP_1
FFREE_1
FIADDm16_2
FIADDm32_2
FIDIVRm16_2
FIDIVRm32_2
FIDIVm16_2
FIDIVm32_2
FILDm16_1
FILDm32_1
FILDm64_1
FIMULm16_2
FIMULm32_2
FINCSTP_1
FISTPm16_1
FISTPm32_1
FISTPm64_1
FISTTPm16_1
FISTTPm32_1
FISTTPm64_1
FISTm16_1
FISTm32_1
FISUBRm16_2
FISUBRm32_2
FISUBm16_2
FISUBm32_2
FLD1_ST0_1
FLD2E_ST0_1
FLD2T_ST0_1
FLDLG2_ST0_1
FLDLN2_ST0_1
FLDPI_ST0_1
FLDZ_ST0_1
FLDm32_1
FLDm64_1
FLDst0_1
FLDst1_1
FMULP_2
FMULPst1_2
FMULm32_2
FMULm64_2
FMULst1_2
FNOP_1
FPATAN_1
FPREM1_2
FPREM_2
FPTAN_1
FRNDINT_1
FSCALE_1
FSINCOS_1
FSIN_1
FSQRT_1
FSTPm32_1
FSTPm64_1
FSTPst_1
FSTm32_1
FSTm64_1
FSTst_1
FSUBP_2
FSUBPst1_2
FSUBRP_2
FSUBRPst1_2
FSUBRm32_2
FSUBRm64_2
FSUBRst1_2
FSUBm32_2
FSUBm64_2
FSUBst1_2
FTST_1
FUCOMIPst0st2_2
FUCOMIst0st2_2
FUCOMPPst0st1_2
FUCOMPst0st1_2
FUCOMPst0st2_2
FUCOMst0st1_2
FUCOMst0st2_2
FXAM_1
FXCHst0st0_1
FXCHst0st1_1
FXCHst0st2_1
FY2LXP1_1
FY2LX_1

Full log attached. amd_output.txt.gz

spotlightishere commented 1 year ago

I'm encountering this issue while building the Docker image on a Zen 4 system - these tests seem to only fail at the offset of the x87 FPU state last instruction pointer, and the native bytes appear to always be zero.

From my (very limited, please correct if wrong!) understanding, it seems like this is intentional according to AMD's x87 manual:

FXSAVE does not save the x87 pointer registers (last instruction pointer, last data pointer, and last opcode), except in the relatively rare cases in which the exception-summary (ES) bit in the x87 status word is set to 1, indicating that an unmasked x87 exception has occurred.

Given that the last opcode/data pointer are currently set to zero, would it make sense to resolve this issue by also setting the instruction pointer to zero?

pgoodman commented 1 year ago

@spotlightishere this sounds like a good PR to make. I think right now we have the tracking of the x87 fp/dp as enabled/disabled via a macro. It seems like regardless of this macro, we should be checking this bit in a few places and zeroing out some things.