Menu

#295 Win64 Fixup issues starting with 2.10

v210
open
nobody
None
5
2013-11-21
2013-11-20
Calvados
No

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:

define MAX_LINE_LEN 8792 / no restriction for this number /

define MAX_ID_LEN 8192 / must be < MAX_LINE_LEN /

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.

1 Attachments

Discussion

  • japheth

    japheth - 2013-11-20

    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.

     
  • Calvados

    Calvados - 2013-11-21

    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
  • japheth

    japheth - 2013-11-21

    The fix will almost certainly be 1 additional line in coff.c, function coff_write_section_table():

    } else if ( curr->e.seginfo->segtype == SEGTYPE_BSS || segtype == SEGTYPE_BSS ) {
        /* v2.12: if segtype is bss, ensure that seginfo->segtype is also bss; else
         * the segment might be written in coff_write_data().
         */
        curr->e.seginfo->segtype = SEGTYPE_BSS;  /* added */
        ish.Characteristics |= IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
    

    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

    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.

     
  • Calvados

    Calvados - 2013-11-21

    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?

     
  • japheth

    japheth - 2013-11-21

    however it seems to work fine.

    Strange. I guess the ADDR32 fixups are generated by those source lines:

    jump_label$0000094e: 
    DD  jump_label$0000081f 
    DD  jump_label$0000081e 
    DD  jump_label$0000084a 
    DD  jump_label$0000084d 
    DD  jump_label$00000844 
    DD  jump_label$0000085b 
    DD  jump_label$00000860 
    DD  jump_label$00000847 
    DD  jump_label$00000845 
    DD  jump_label$00000846 
    DD  jump_label$0000084f 
    DD  jump_label$00000853 
    DD  jump_label$00000854
    

    So the fixup has to be 4 bytes. I guess ML64 would also generate ADDR32 fixups in these cases.

     

Log in to post a comment.