Terraspace / UASM

UASM - Macro Assembler
http://www.terraspace.co.uk/uasm.html
Other
220 stars 49 forks source link

Handful of errors with PTR PROTO structure member #132

Closed vid512 closed 2 months ago

vid512 commented 4 years ago

This code works correctly: (compile with -win64 option)

option casemap:none    ;needed for windows.inc

.code
code_start:

myfunc       proto :PTR
PROTO_myfunc typedef proto :PTR
PTR_myfunc   typedef ptr PROTO_myfunc

MYSTRUC struct
  myfunc PTR_myfunc ?
MYSTRUC ends

mystruc MYSTRUC <>

mov  [rbp + (mystruc.myfunc - code_start)], rcx

myfunc PROC file_name:PTR
  RET
myfunc ENDP

end

But if you move the mystruc definition behind the myfunc defition, you get error "Conflicting parameter definition" on definition of myfunc.

option casemap:none

.code
code_start:

myfunc       proto :PTR
PROTO_myfunc typedef proto :PTR
PTR_myfunc   typedef ptr PROTO_myfunc

MYSTRUC struct
  myfunc PTR_myfunc ?
MYSTRUC ends

mov  [rbp + (mystruc.myfunc - code_start)], rcx

myfunc PROC file_name:PTR
  RET
myfunc ENDP

mystruc MYSTRUC <>

end

If you move the definition of mystruc between MOV and defition of myfunc, you get the same error and then a General Failure:

option casemap:none

.code
code_start:

myfunc       proto :PTR
PROTO_myfunc typedef proto :PTR
PTR_myfunc   typedef ptr PROTO_myfunc

MYSTRUC struct
  myfunc PTR_myfunc ?
MYSTRUC ends

mov  [rbp + (mystruc.myfunc - code_start)], rcx

mystruc MYSTRUC <>

myfunc PROC file_name:PTR
  RET
myfunc ENDP

end

If you change the MOV instruction to access the structure member directly, you get one more weird error, saying "Operands must be the same size: 2 - 8" on the MOV instruction:

option casemap:none

.code

myfunc       proto :PTR
PROTO_myfunc typedef proto :PTR
PTR_myfunc   typedef ptr PROTO_myfunc

MYSTRUC struct
  myfunc PTR_myfunc ?
MYSTRUC ends

mov  [mystruc.myfunc], rcx

mystruc MYSTRUC <>

myfunc PROC file_name:PTR
  RET
myfunc ENDP

end

Something seems very wrong...

vid512 commented 4 years ago

I have discovered this bug is not actually caused by the structure member being of PTR PROTO type, but instead by the structure member being named same as PROC. If you change the type of member to "myfunc DQ ?" you still get all the same errors. However if you rename the structure member to something else, errors go away.

vid512 commented 4 years ago

I vaguely remember this problem from JWASM days. It was about the WinInc structure DEBUG_EVENT having member ExitProcess, causing trouble with API function ExitProcess in some scenarios. I think it was somehow fixed at the time, but apparently the fix was not fully correct.

VitorEAFeliciano commented 3 years ago

Clearly declaring data outside segment data its not fully supported by UASM. But we can write .data to uasm knows wath to do or not...


.code

myfunc       proto :PTR
PROTO_myfunc typedef proto :PTR
PTR_myfunc   typedef ptr PROTO_myfunc

.data?
MYSTRUC struct
  myfunc PTR_myfunc ?
MYSTRUC ends

mystruc MYSTRUC <>  ;;Work's

.data
mystruct2 struct
  aa db ?
  bb dw ?
  cc dd ?
  sdd dq ?
mystruct2 ends

;align 16
;struct2 mystruct2 <>  ;;Don't work in linux object assembling... initialized segment data. Throw General Failure. But works in windows object assembling...

mystruct3 struct
  aa3 db ?
  bb3 dw ?
  cc3 dd ?
  sdd3 dq ?
mystruct3 ends

.data?
align 16
struct3 mystruct3 <>  ;;This works

.code

mov  [mystruc.myfunc], rcx

myfunc PROC file_name:PTR
  RET
myfunc ENDP

Going to see wath I can do...

VitorEAFeliciano commented 3 years ago

This hapens in Linux only object assembling. UASM sucessfuly assembles for windows. Needs a fix for linux, not directly related, but affects.

kradmoonra@kradmoonra:~/projects/uasm/bin/test$ gdb --args ./uasmd -c -Cp -archAVX -W0 -Gy -zf4 -mf -elf64 -pie -I /usr/include/uasm -Fo testlinux.o testlinux.asm
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./uasmd...
(gdb) b exit
Breakpoint 1 at 0xa280
(gdb) run
Starting program: /home/kradmoonra/projects/uasm/bin/test/uasmd -c -Cp -archAVX -W0 -Gy -zf4 -mf -elf64 -pie -I /usr/include/uasm -Fo testlinux.o testlinux.asm
UASM v2.51.1, Mar 15 2021, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

testlinux.asm : Internal error in /home/kradmoonra/projects/uasm/elf.c(1331)

Breakpoint 1, __GI_exit (status=1) at exit.c:138
138     exit.c: No such file or directory.
(gdb) backtrace
#0  __GI_exit (status=1) at exit.c:138
#1  0x0000555555597cb2 in InternalError (file=0x555555652202 "/home/kradmoonra/projects/uasm/elf.c", line=1331) at projects/uasm/errmsg.c:473
#2  0x0000555555592cf4 in elf_write_data (modinfo=0x55555566d3a0 <ModuleInfo>, em=0x7fffffffd4b0) at projects/uasm/elf.c:1331
#3  0x0000555555591fa6 in elf_write_module (modinfo=0x55555566d3a0 <ModuleInfo>) at projects/uasm/elf.c:1469
#4  0x00005555555609c2 in WriteModule (modinfo=0x55555566d3a0 <ModuleInfo>) at projects/uasm/assemble.c:590
#5  0x000055555555fef8 in AssembleModule (source=0x5555556bd8a0 "testlinux.asm") at projects/uasm/assemble.c:1900
#6  0x00005555555da658 in main (argc=15, argv=0x7fffffffe978) at projects/uasm/main.c:156
(gdb) quit
A debugging session is active.

        Inferior 1 [process 87466] will be killed.

Quit anyway? (y or n) y
kradmoonra@kradmoonra:~/projects/uasm/bin/test$
static ret_code elf_write_data(struct module_info* modinfo, struct elfmod* em)
/******************************************************************************/
{
    struct dsym*    curr;
    //int seg_index;
    //uint_32 offset = 0;
    uint_32         size;
    int             i;

    DebugMsg(("elf_write_data: enter\n"));

    for (curr = SymTables[TAB_SEG].head; curr; curr = curr->next)
    {
        size = curr->sym.max_offset - curr->e.seginfo->start_loc;
        DebugMsg(("elf_write_data(%s): program data at ofs=%X, size=%X\n", curr->sym.name, curr->e.seginfo->fileoffset, size));
        if (curr->e.seginfo->segtype != SEGTYPE_BSS && size != 0)
        {
            fseek(CurrFile[OBJ], curr->e.seginfo->fileoffset + curr->e.seginfo->start_loc, SEEK_SET);
            /**/myassert(curr->e.seginfo->CodeBuffer == NULL);  /*TODO-Issues-#132-KRAD-(add null comparison... Clearly, the CodeBuffer gets cleared somewhere. data struct string declaration outside uninitialized segment!)*/
            if (fwrite(curr->e.seginfo->CodeBuffer, 1, size, CurrFile[OBJ]) != size)
                WriteError();
        }
    }

    /* write internal sections */
    for (i = 0; i < NUM_INTSEGS; i++)
    {
        if (em->internal_segs[i].data)
        {
            DebugMsg(("elf_write_data(%s): internal at ofs=%X, size=%X\n", internal_segparms[i].name, em->internal_segs[i].fileoffset, em->internal_segs[i].size));
            fseek(CurrFile[OBJ], em->internal_segs[i].fileoffset, SEEK_SET);
            if (fwrite(em->internal_segs[i].data, 1, em->internal_segs[i].size, CurrFile[OBJ]) != em->internal_segs[i].size)
                WriteError();
        }
    }

    /* write reloc sections content */
    for (curr = SymTables[TAB_SEG].head; curr; curr = curr->next)
    {
        if (curr->e.seginfo->num_relocs)
        {
            DebugMsg(("elf_write_data(%s): relocs at ofs=%X, size=%X\n", curr->sym.name, curr->e.seginfo->reloc_offset, curr->e.seginfo->num_relocs * sizeof(Elf32_Rel)));
            fseek(CurrFile[OBJ], curr->e.seginfo->reloc_offset, SEEK_SET);
#if AMD64_SUPPORT
            if (modinfo->defOfssize == USE64)
                write_relocs64(curr);
            else
#endif
                write_relocs32(em, curr);
        }
    }
#if GNURELOCS
    if (em->extused)
    {
        EmitWarn(2, ELF_GNU_EXTENSIONS_USED);
    }
#endif

    DebugMsg(("elf_write_data: exit\n"));

    return(NOT_ERROR);
}
john-terraspace commented 2 years ago

Did you guys have a resolution for this issue, perhaps we can PR it into the new 2.55 branch? - I've not tested on Linux, but the above cases and the one in https://github.com/Terraspace/UASM/issues/145 seem to work fine on Windows.

john-terraspace commented 2 years ago

Couldn't reproduce this issue using this test-case:

.x64 .model flat

something STRUCT myproc dq ? something ENDS

.code

myproc proto

mov [(type something.myproc) ptr [rax]], rax

a db 0

myproc PROC RET myproc ENDP

end

vid512 commented 2 years ago

What is that test-case, and how is it relevant to the issue? All of test-cases that I have reported in both my original posts still produce same error with UASM 1.52 on Windows.

Note that, as I said in original post, the error doesn't happen always when there is a structure member named same as proc. Only sometimes, and the particular error is dependent on order of things referencing this problematic entity. I wouldn't be surprised if the error was dependent on outside OS influences, such as referencing values from uninitialized buffer etc.

john-terraspace commented 2 years ago

That was the code from your other issue (#145). I was curious if Vitor had any changes that fixed the issue if it was more persistent on Linux as noted above. I will continue trying some variations to see if I can get something that consistent produces the issue.

vid512 commented 2 years ago

It wasn't the code from #145, you have added structure declaration to it, which causes the bug not to trigger. My code in first post of #145 is interesting precisely because it causes GF without the structure being declared at all, just using the symbol as if it was structure member is enough to cause GF. That might reveal some info about the nature of the bug. And yes, it still happens with UASM 2.52.

john-terraspace commented 2 years ago

I've fixed the cause of the general failure, that was a symbol type check using the altname field which didn't exist (null ptr).