NO

Author Topic: polink issue ?  (Read 1169 times)

Offline jk

  • Member
  • *
  • Posts: 7
polink issue ?
« on: August 23, 2023, 08:33:52 PM »
By chance i came across this problem. I have an app, which tests error recovery features. Linking the . obj file with MS´s linker just works fine, using polink the resulting .exe crashes. Investigating this further i found that polink resolves the local label "__el1" incorrect as it seems (assembler snippet "error.asm" line 18). This label name ("__el1") occurs in more than one procedure, but this shouldn´t be a problem, because it is a local label. Polink makes the corresponding jump go into a different procedure to a label with the same name, which leads to GPF further on. The attached .obj file has got inserted an "int 3" before the offending "jmp" in order to be able to easily find the error location with a debugger. Please study the supplied files in the attachment.

Thanks

JK

Offline Vortex

  • Member
  • *
  • Posts: 802
    • http://www.vortex.masmcode.com
Re: polink issue ?
« Reply #1 on: August 24, 2023, 09:25:53 AM »
Hi jk,

Could you please provide the complete source code so we can reproduce the issue?
Code it... That's all...

Offline jk

  • Member
  • *
  • Posts: 7
Re: polink issue ?
« Reply #2 on: August 24, 2023, 01:36:53 PM »
The original source is assembler and i use a very special setup, which at the moment is WIP and therefore scattered all over my HD - could be a major task reproducing.

That is why i supplied the assembled .obj file. As said avove the error occurs when linking with polink, it doesn´t occur with MS´s linker from Visual Studio. MS´s stuff is overbloated for what i need, therefore i tried polink. It works perfectly well in all of my other apps, but it fails here (al least i suppose it´s a linker problem).

The attachement contains the .obj file, the resulting .exe files for polink.exe and link.exe (MS), the batch commandline for polink (incl. command file), two debugger screenshots and a snippet of the relevant assembler code. As you can see, this isn´t regular assembler code, among other things my setup maps e.g xax to eax and rax respectively, that is, the same code can be assembled in 32 and 64 bit.

As already said above, my current best bet is, that the jump address in line 18 of the snippet isn´t "calculated" correctly in the linking process, because the name of the label "__el1" is not unique. It is unique per procedure, but it is not unique all over the .obj file, because a label with same name is present in several procedures. I hope this is sufficient data to investigate what happens.

Offline John Z

  • Member
  • *
  • Posts: 796
Re: polink issue ?
« Reply #3 on: August 24, 2023, 02:50:26 PM »
Hi jk,

So have you tried to prove it is a multiple label name use issue by changing to unique names?
From what you said there should be no issue using unique names since they are supposed to
be procedure scoped.  And this should be a relatively minor edit.

Trying to figure out a potential bug from the output result files is much more difficult than starting
from the sources.  Perhaps you can created a demo version with just one or two procedures using
an identical 'local' label that shows the bug resulting in a link error.

John Z



Offline jk

  • Member
  • *
  • Posts: 7
Re: polink issue ?
« Reply #4 on: August 24, 2023, 09:56:39 PM »
I can confirm, that making the offending label name unique over all procedures makes the problem go away.

To my understanding the error occurs somewhere in the linking process, otherwise the executable linked with MS´s linker wouldn´t run properly. In the attachment of post #1 i supplied the . obj file, which is all you need for linking it yourself, as well as additional info as far as i could. I don´t see the advantage of being able to create the .obj file yourself, when you already have this .obj file. In my opinion only the developer(s) of polink can tell, what is wrong here.

I don´t claim that polink is buggy! But i have an .obj file which (when linked to an executable) works fine with MS´s linker and doesn´t with polink. So at first glance there are two options:
- it could be a bug inside the .obj file, but then it would be crucial to have this file for testing and finding out, what´s wrong with the .obj file
- it could be a bug in polink and then it is equally essential to have exactly this .obj file   

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2091
Re: polink issue ?
« Reply #5 on: August 25, 2023, 11:18:54 AM »
MAP-file might be useful for checking things ?
May the source be with you

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: polink issue ?
« Reply #6 on: August 25, 2023, 12:51:17 PM »
I don't know exactly what is happening here, but I suppose that the result could be related at least to 2 different things.
The first is that the symbol, even if not declared global or extern, isn't considered 'local' by the compiler assembler (sorry, but I was used to C compiler  ;D).
The second point could be the recently added "select_any" behavior, introduced in version 11, that for multiply defined symbols simply pick one of them.
This is just a speculation  :P
« Last Edit: August 25, 2023, 02:57:29 PM by frankie »
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline John Z

  • Member
  • *
  • Posts: 796
Re: polink issue ?
« Reply #7 on: August 25, 2023, 02:12:34 PM »
I've not done any Intel CPU assembly programing since the 486 came out ;( but looking to refresh my knowledge and for information I found this:
---
Labels

A label can be placed at the beginning of a statement. During assembly, the label is assigned the current value of the active location counter and serves as an instruction operand. There are two types of lables: symbolic and numeric.
Symbolic Labels

A symbolic label consists of an identifier (or symbol) followed by a colon (:) (ASCII 0x3A). Symbolic labels must be defined only once. Symbolic labels have global scope and appear in the object file's symbol table.

Symbolic labels with identifiers beginning with a period (.) (ASCII 0x2E) are considered to have local scope and are not included in the object file's symbol table.
---

If poasm/polink follows this rule then try putting a . in front of the labels that are to be local in scope. This should be easy to try .. the linker may be looking for this identifier.

John Z
reference link (maybe outdated) https://docs.oracle.com/cd/E26502_01/html/E28388/eqbsx.html
« Last Edit: August 25, 2023, 11:25:35 PM by John Z »

Offline jk

  • Member
  • *
  • Posts: 7
Re: polink issue ?
« Reply #8 on: August 25, 2023, 09:37:44 PM »
I can confirm, that it doesn´t depend on the version of polink, the problem occurs with V 9 as well as with the latest (just tested).

The term "label" alone might be ambiguos, in this case "label" means a jump target, a location in code, where absolute or conditional jumps go to. In assembler code these "labels" must end with a colon, labels with local (procedure) scope get one single colon (e.g. "label:"), global labels get two consecutive colons (e.g. "global_label::"). A dot as first charcater is not allowed, the first character can be an alphabetic character (a-z, A–Z) or any of these four characters: "@ _ $ ?"

Offline John Z

  • Member
  • *
  • Posts: 796
Re: polink issue ?
« Reply #9 on: August 26, 2023, 11:06:38 AM »
Well I'll throw out one more thought then let it be as I'm certainly no expert - Vortex where are you  ?? ;)

Pelles Help File:
"The assembler contains a parser for the IA32 (X86) and AMD64 (X86-64) architecture with a syntax similar to MASM, but there are deliberate differences since POASM is not intended to be an exact clone of MASM."

----
https://fragglet.github.io/dos-help-files/alang.hlp/x_cln__cln_.html
 "With the single colon, <label> has global scope within its
     module under the default OPTION NOSCOPED. Under OPTION SCOPED,
     <label> is LOCAL inside a PROC block and is global elsewhere.
     The <label> cannot be declared public.
 
     The double colon acts the same as the single colon except that
     <label> has global scope within its module, independent of OPTION
     SCOPED, and can be declared PUBLIC."
---
Art of Assembly Language chapter 12
https://www.plantation-productions.com/Webster/www.artofasm.com/DOS/ch12/CH12-1.html#HEADING1-9   
"By default, MASM 6.x treats statement labels (those with a colon after them) as local to a procedure.
MASM uses the following default scoping rules:

    By default, statement labels appearing in a procedure are local to that procedure.
    By default, all procedure names are public.
    By default, most other symbols are global.

Note that these rules apply to MASM 6.x only. Other assemblers and earlier versions of MASM follow different rules.

Overriding the default on the first rule above is easy - either use the option noscoped statement or use a double colon to make a label global. You should be aware, though, that you cannot make a local label public using the public or externdef directives. You must make the symbol global (using either technique) before you make it public."
----

Makes me believe poasm follows the first "default OPTION NOSCOPED", additionally the poasm help
file makes no mention of having options for NOSCOPED or SCOPED that I could find.

That's all folks ....

John Z

Offline jk

  • Member
  • *
  • Posts: 7
Re: polink issue ?
« Reply #10 on: August 26, 2023, 11:08:48 AM »
Ok, i boiled it down to the absolute minimum:

Code: [Select]

ExitProcess PROTO :DWORD
TESTME PROTO

includelib KERNEL32.LIB


.CODE


TESTME PROC USES EBX ESI EDI
;*************************************************************************************
;
;*************************************************************************************
LOCAL _res:XWORD


  xor eax, eax


__el1:
  test eax, eax
  jne L2


  lea ebx, __el1
  mov _res, ebx
  jmp L1   ;jmp to error handler


; some other code


L1:
  add eax, 1
  JMP _res


L2:


RET


TESTME ENDP


start PROC USES EBX ESI EDI
;*************************************************************************************
;
;*************************************************************************************
LOCAL _res:XWORD


  invoke TESTME


int 3
  xor edx, edx


__el1:
  test edx, edx
  jne L2


  lea ebx, __el1
  mov _res, ebx
  jmp L1   ;jmp to error handler


; some other code


L1:
  add edx, 1
  JMP _res


L2:

INVOKE ExitProcess, edx


start ENDP


END start



Regardless which assembler i use (ml.exe, asmc.exe, uasm.exe) linking with MS´s link.exe works, linking with polink leads to error (see attachments)

Offline jk

  • Member
  • *
  • Posts: 7
Re: polink issue ?
« Reply #11 on: August 26, 2023, 11:13:23 AM »
Seems the attached images got lost

Offline John Z

  • Member
  • *
  • Posts: 796
Re: polink issue ?
« Reply #12 on: August 26, 2023, 11:18:17 AM »
Great -

Seems you did not try poasm?  I don't see it mentioned.
If poasm only uses default NOSCOPED then polink which
is written for poasm would not be expecting otherwise so
linking with polink but using other asm programs would be
an incompatibility.  The three assemblers below I expect are
highly compatible with MASM 6.1

John Z

Offline Vortex

  • Member
  • *
  • Posts: 802
    • http://www.vortex.masmcode.com
Re: polink issue ?
« Reply #13 on: August 26, 2023, 11:31:54 AM »
Hi Jk,

A question :

Code: [Select]
TESTME PROC USES EBX ESI EDI
;*************************************************************************************
;
;*************************************************************************************
LOCAL _res:XWORD


  xor eax, eax


__el1:
  test eax, eax
  jne L2


  lea ebx, __el1
  mov _res, ebx
  jmp L1   ;jmp to error handler


; some other code


L1:
  add eax, 1
  JMP _res

What is XWORD?
« Last Edit: August 26, 2023, 12:08:06 PM by Vortex »
Code it... That's all...

Offline Vortex

  • Member
  • *
  • Posts: 802
    • http://www.vortex.masmcode.com
Re: polink issue ?
« Reply #14 on: August 26, 2023, 11:57:50 AM »
Hi Jk,

After replacing the XWORDs with DWORDs, I managed to assemble your source code with Poasm. Disassembling the object module with Agner Fog's objconv :

Code: [Select]
.386
option dotname
.model flat

public _TESTME@0
public _start@0

extern _ExitProcess@4: near

@feat.00 equ 00000001H                                 


.drectve SEGMENT BYTE PUBLIC 'CONST'                   

        db 2FH, 64H, 65H, 66H, 61H, 75H, 6CH, 74H       
        db 6CH, 69H, 62H, 3AH, 4BH, 45H, 52H, 4EH       
        db 45H, 4CH, 33H, 32H, 2EH, 4CH, 49H, 42H       
        db 20H, 2FH, 65H, 6EH, 74H, 72H, 79H, 3AH       
        db 73H, 74H, 61H, 72H, 74H, 40H, 30H, 20H       

.drectve ENDS

_text   SEGMENT PARA PUBLIC 'CODE'                     

_TESTME@0 PROC NEAR
        push    ebp                                     
        mov     ebp, esp                               
        sub     esp, 4                                 
        push    ebx                                     
        push    esi                                     
        push    edi                                     
        xor     eax, eax                               

TESTME.__el1 LABEL NEAR
        test    eax, eax                               
        jnz     ?_002                                   
        lea     ebx, [TESTME.__el1]                     
        mov     dword ptr [ebp-4H], ebx                 
        jmp     ?_001                                   

?_001:  add     eax, 1                                 
        jmp     dword ptr [ebp-4H]                     
_TESTME@0 ENDP

?_002   LABEL NEAR
        pop     edi                                     
        pop     esi                                     
        pop     ebx                                     
        leave                                           
        ret                                             

_start@0 PROC NEAR
        push    ebp                                     
        mov     ebp, esp                               
        sub     esp, 4                                 
        push    ebx                                     
        push    esi                                     
        push    edi                                     
        call    _TESTME@0                               
        int     3                                       
        xor     edx, edx                               

start.__el1 LABEL NEAR
        test    edx, edx                               
        jnz     ?_004                                   
        lea     ebx, [start.__el1]                     
        mov     dword ptr [ebp-4H], ebx                 
        jmp     ?_003                                   

?_003:  add     edx, 1                                 
        jmp     dword ptr [ebp-4H]                     
_start@0 ENDP

?_004   LABEL NEAR
        push    edx                                     
        call    _ExitProcess@4                         
        pop     edi                                     
        pop     esi                                     
        pop     ebx                                     
        leave                                           
        ret                                             

_text   ENDS

END

Could you please show the issue(s) here in this output?

Listing the symbols of the object module :

Code: [Select]
E:\PellesC\Bin>podump.exe /SYMBOLS test.obj

Dump of erol.obj

File type: OBJ

SYMBOL TABLE
0000 00000001 ABS    notype      static       | @feat.00
0001 00000000 SECT1  notype      static       | .drectve
     length of section   28, #relocations    0, #linenumbers    0
0003 00000000 SECT2  notype      static       | .text
     length of section   57, #relocations    3, #linenumbers    0
0005 00000000 UNDEF  notype      external     | _ExitProcess@4
0006 00000000 SECT2  notype ()   external     | _TESTME@0
0007 00000025 SECT2  notype ()   external     | _start@0
0008 0000000B SECT2  notype      static       | TESTME.__el1
0009 00000037 SECT2  notype      static       | start.__el1

SUMMARY
      28 .drectve
      57 .text

Removing the instruction int 3, I rebuilt the application. A session of Ollydbg didn't report any issues.
« Last Edit: August 26, 2023, 12:16:46 PM by Vortex »
Code it... That's all...