Win64 Fixup issues starting with 2.10
Brought to you by:
japheth
I have just started to deal with win64, and I noticed a problem with FIXUP emission. Since v2.10, if the file is big enough it outputs NULL (ABSOLUTE) fixups. 2.07,2.08,2.09 are immune to the issue, 2.10/2.11/2.11a have the problem.
The attached file should allow you to reproduce the problem. You will need to recompile JWASM with the following modified in globals.h:
I will try to look into it on my side, but I am not very hopefull. The amount of changes between 2.09 and 2.10 is rather huge.
I did a few tests.
The problem seems to be that jwasm calculates the file offsets of section data and section relocations incorrectly, because it is confused by the segment named '_BSS'.
This segment has no class, and hence jwasm doesn't recognize it as of type BSS and hence it is included in the object module ( a huge pile of '00' bytes ).
If you change line
_BSS segment
to
_BSS segment 'BSS'
then jwasm is no longer confused, the calculations are correct and the weird relocations will disappear.
This is a work-around only, of course; jwasm's inconsistent behavior has to be fixed eventually - but this will require a few more investigations.
Verified to work - Funnily enough, I was going to address the segment problem today, because it created a huge binary ;).
On a side note, I have found that Microsoft LINK for WIN64 target doesn't like ADDR32 fixups and wants ADDR32NB instead (compiler generated binaries don't have any ADDR32 records ever). I modified coff_write_fixups to do so when it encounters FIX_OFF32 in AMD64 block.
Thanks anyway, and I hope you find what's wrong eventually :).
Last edit: Calvados 2013-11-21
The fix will almost certainly be 1 additional line in coff.c, function coff_write_section_table():
I'm a bit doubtfully that this replacement is ok. ADDR32NB is a RVA address, that is, the image base is not added to the final address - while ADDR32 is just the lower 32-bits of a "full" address that includes the image base.
I have applied your proposed fix, and it correct the issue. As for the ADDR32NB thing, I was highly skeptical too (I tried and totally expected it to barf on me), however it seems to work fine. Would you suggest another location to apply such a change?
Strange. I guess the ADDR32 fixups are generated by those source lines:
So the fixup has to be 4 bytes. I guess ML64 would also generate ADDR32 fixups in these cases.