Describe the bug
If a function takes a 64-bit float parameter and then proceeds to compare it to 0 (MOVSD->UCOMISD->LAHF->TEST->JNP), Ghidra considers the non-0 branch to be dead code and for parameter to be unused.
To Reproduce
#include "pch.h"
extern "C" __declspec(dllexport) void __cdecl test(double enable, HWND hwnd) {
if (enable != 0) {
MessageBoxA(hwnd, "Not 0!", "", MB_OK);
} else {
MessageBoxA(hwnd, "0!", "", MB_OK|MB_ICONERROR);
}
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
return TRUE;
}
test function in Exports and take a look at decompile view.You get this:
void __cdecl _test(undefined4 param_1,undefined4 param_2,HWND param_3)
{
/* 0x1000 1 test
Symbol Ref: _test */
if (false) {
MessageBoxA(param_3,"Not 0!","",0);
return;
}
MessageBoxA(param_3,"0!","",0x10);
return;
}
(then-branch is considered to be dead code; 8-byte parameter is interpreted as two unknown4s)
Expected behavior
Recognizing MOSD/UCOMISD as a sign of the parameter being a 64-bit float, or, failing that, showing a comparison to literal's raw floating-point value.
Attachments
Pre-compiled version of the sample DLL
Environment (please complete the following information):
Additional context
The shared trait between this and my original code is use of MOVSD+UCOMISD for value != 0 comparisons, perhaps this is the source of trouble
10001000 55 PUSH EBP
10001001 8b ec MOV EBP,ESP
10001003 f2 0f 10 MOVSD XMM0,qword ptr [EBP + param_1]
45 08
10001008 66 0f 2e UCOMISD XMM0,qword ptr [__real@0000000000000000]
05 b0 20
00 10
10001010 9f LAHF
10001011 f6 c4 44 TEST AH,0x44
10001014 7b 17 JNP LAB_1000102d
...
(from sample)
assume you tested with a correct prototype, does that change anything?
Hello, sorry, I forgot to include this in the issue text after moving things around - updating the function signature to match expected types doesn't seem to do anything for it,
void __cdecl _test(double val,HWND hwnd)
{
/* 0x1000 1 test
Symbol Ref: _test */
if (false) {
MessageBoxA(hwnd,"Not 0!","",0);
return;
}
MessageBoxA(hwnd,"0!","",0x10);
return;
}
~Ah, looks that instruction has a todo~
wish github search was better, searching for UCOMISD goes to VUCOMISD, which does have todo, but UCOMISD looks implemented
I think mine might be the same thing as this previously described issue https://github.com/NationalSecurityAgency/ghidra/issues/122
This problem was caused by the parity flag not being modeled for x86. This is now fixed in master and the upcoming 9.2
Most helpful comment
This problem was caused by the parity flag not being modeled for x86. This is now fixed in master and the upcoming 9.2