I have written a script that compares all references to the stack between the original and the recompiled binary. This is especially useful for BETA10, where it can be hard to tell if the order of variables on the stack is wrong or if there is an actual logic error in the recomp (the wrong variable is read or written). The script may also help understand how msvc decides the stack order since the analysis is much faster now. The names of the variables are pulled from the debug info.
Looking forward to your feedback - especially whether the built-in explanations are clear and/or how they could be improved.
Here is the abbreviated output for ther same function as it is on master right now, with a slight structural mismatch:
Note how ebp - 0x18 is listed under not seen since its only appearance is in the structural mismatch. It could also be that it only appears in the middle of a perfectly matching block which - those are always omitted from the output (like in reccmp).
This script works best when the structure of the two functions matches perfectly, and only the stack layout differs. Structural mismatches are skipped since it cannot be determined automatically which instructions correspond.
I suspect there will be some issues with release builds, where I have not yet looked extensively for interesting cases to analyse.
As far as I can tell, debug builds only ever reference variables relative to ebp, never from esp. This is different for release builds, which reference the stack both from ebp and from esp.
I assume that the references from esp do not work correctly under some circumstances. It will likely be necessary to keep track of the stack size (i.e. parse at least every sub esp, ..., add esp, ..., push, call). This is not implemented right now.
I am not sure how well this code handles reused stack variables in LEGO1. It is possible that the S_BLOCK32 entries in the PDB need to be parsed and each block handled separately.
I have written a script that compares all references to the stack between the original and the recompiled binary. This is especially useful for BETA10, where it can be hard to tell if the order of variables on the stack is wrong or if there is an actual logic error in the recomp (the wrong variable is read or written). The script may also help understand how
msvc
decides the stack order since the analysis is much faster now. The names of the variables are pulled from the debug info.Looking forward to your feedback - especially whether the built-in explanations are clear and/or how they could be improved.
Example outputs Here is the (slightly abbreviated) output for a modified version of
LegoCarBuildAnimPresenter::FUN_10079160()
that matches up to the order of stack variables (renameroot
toaaaroot
as declared here): https://github.com/isledecomp/isle/blob/974cd7ce7c727d21652c8383f0c58910fce87602/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp#L261Here is the abbreviated output for ther same function as it is on
master
right now, with a slight structural mismatch: Note howebp - 0x18
is listed undernot seen
since its only appearance is in the structural mismatch. It could also be that it only appears in the middle of a perfectly matching block which - those are always omitted from the output (like inreccmp
).Here is the abbreviated output for the same function with an intentional logic error -
counter++
is replaced byi++
in the following line: https://github.com/isledecomp/isle/blob/974cd7ce7c727d21652c8383f0c58910fce87602/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp#L326Limitations
Compare.compare_address()
. This will likely require changes around the following line, such that thecontext_size
can be set very high or disabled entirely: https://github.com/isledecomp/isle/blob/974cd7ce7c727d21652c8383f0c58910fce87602/tools/isledecomp/isledecomp/compare/core.py#L717ebp
, never fromesp
. This is different for release builds, which reference the stack both fromebp
and fromesp
.esp
do not work correctly under some circumstances. It will likely be necessary to keep track of the stack size (i.e. parse at least everysub esp, ...
,add esp, ...
,push
,call
). This is not implemented right now.S_BLOCK32
entries in the PDB need to be parsed and each block handled separately.