YES_EXPORT PROC
;; ...
#ifdef fg_pe
if (OUTPUT_PE) // false on first test
TWEAK_EXPORT_NAMES();
#endif
DEFINE_EXPORT(); // could set ANY_USE32, but it's usually already
SELECT_OUTPUT_SEGMENTED_OR_PE();
;; ...
YES_EXPORT ENDP
SELECT_OUTPUT_SEGMENTED_OR_PE PROC
if (!(OUTPUT_SEGMENTED | OUTPUT_PE))
return;
if (ANY_USE32) // this is already set by defining the output segments
SELECT_OUTPUT_PE(); // sets OUTPUT_PE
else
SELECT_OUTPUT_SEGMENTED();
SELECT_OUTPUT_SEGMENTED_OR_PE ENDP
I found the bug, thanks to OllyDbg, but I could use some help to interpret and resolve it.
From what I understand optlink determines the output format OUTPUT_SEGMENTED or OUTPUT_PE depending on the input files. That is when it first encounters some usage of 32-bit symbols it will set ANY_USE32.
Striping the leading underscore in the exported name is only done for OUTPUT_PE.
The problem comes from the circular dependency in the OUTPUT_PE test above. For the first export symbol no output format has yet been set, thus the test fails and the symbol is not stripped.
One way to resolve this would be to prematurely test for ANY_USE32 if no OUTPUT is selected.
if (OUTPUT_PE || !OUTPUT_SEGMENTED && ANY_USE32)
Any ideas?