flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > How to friend reloc & struct in standard fasmg package

Author
Thread Post new topic Reply to topic
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 17 Jul 2017, 15:02
win32.asm from examples of standart fasmg package
Code:
include 'format/format.inc'

format PE GUI
entry start

;added============
COLOR_BTNFACE   = 15

include 'struct.inc'

struct WNDCLASS
  style         dd ?
  lpfnWndProc   dd ?
  cbClsExtra    dd ?
  cbWndExtra    dd ?
  hInstance     dd ?
  hIcon         dd ?
  hCursor       dd ?
  hbrBackground dd ?
  lpszMenuName  dd ?
  lpszClassName dd ?
ends
;=================

section '.text' code readable executable

  start:

        push    0
        push    _caption
        push    _message
        push    0
        call    [MessageBoxA]

        push    0
        call    [ExitProcess]
;added============
        WindowProc = $
;=================

section '.data' data readable writeable

  _caption db 'Win32 assembly program',0
  _message db 'Hello World!',0
;added============
  _class db 'someclass',0
  wc WNDCLASS style:0, lpfnWndProc:WindowProc, hbrBackground:COLOR_BTNFACE+1, lpszClassName:_class
;=================


section '.idata' import data readable writeable

  dd 0,0,0,RVA kernel_name,RVA kernel_table
  dd 0,0,0,RVA user_name,RVA user_table
  dd 0,0,0,0,0

  kernel_table:
    ExitProcess dd RVA _ExitProcess
    dd 0
  user_table:
    MessageBoxA dd RVA _MessageBoxA
    dd 0

  kernel_name db 'KERNEL32.DLL',0
  user_name db 'USER32.DLL',0

  _ExitProcess dw 0
    db 'ExitProcess',0
  _MessageBoxA dw 0
    db 'MessageBoxA',0

section '.reloc' fixups data readable discardable       ; needed for Win32s
    


struct.inc from fasmg with win32|64 headers
Code:
define struct?
define union?

struct?.counter = -1
struct?.subcounter = -1

struc struct?.init_field name,field,value&
        match =struct type, name.field.__type
                .field struct?.init type,value
        else match =substruct type, name.field.__type

                . struct?.init name.type,value
        else match first=,rest, value
                local data
                virtual at 0
                        emit sizeof .field : value
                        load data : $ from 0
                end virtual
                if lengthof data <= name.field.__length
                        store data : lengthof data at .field
                else
                        err 'data too long for ',`name,'.',`field
                end if
        else if value eqtype ''
                if lengthof value <= name.field.__length
                        store value : lengthof value at .field
                else
                        err 'data too long for ',`name,'.',`field
                end if
        else
                store value at .field
        end if
end struc

struc struct?.init name,args&
        iterate definition, args
                match field:value, definition
                        . struct?.init_field name,field,value
                else match field==value, definition
                        . struct?.init_field name,field,value
                else match value, definition
                        match field, name.__field#%
                                match root.sub, name
                                        . struct?.init_field root,field,value
                                else
                                        . struct?.init_field name,field,value
                                end match
                        end match
                end match
        end iterate
end struc

macro struct? name
        struc name args&
                label . : sizeof.name
                namespace .
                        struct?.name
                end namespace
                . struct?.init name,args
                if struct?.counter > 0
                        repeat 1, i:struct?.counter
                                match field, __field#i
                                        define field.__type struct name
                                end match
                        end repeat
                end if
        end struc
        macro struct?!
                struct?.begin
                esc macro struct?.current
        end macro
        macro struct?.end
                purge struct?.end
                virtual at 0
                        namespace name
                                struct?.counter = 0
                                struct?.subcounter = 0
                                define struct?.substruct
                                struc (field) ? def&
                                        match ==v, def
                                                field def
                                        else match :v, def
                                                field def
                                        else if struct?.counter < 0
                                                field def
                                        else
                                                struct?.counter = struct?.counter + 1
                                                repeat 1, i:struct?.counter
                                                        match sub, struct?.substruct
                                                                define sub.__field#i field
                                                        else
                                                                define __field#i field
                                                        end match
                                                end repeat
                                                field def
                                                if defined field
                                                        field.__length := $ - field
                                                end if
                                        end if
                                end struc
                                struct?.name
                                restruc ?
                                struct?.counter = -1
                                struct?.subcounter = -1
                        end namespace
                        label name:$ at $
                        sizeof.name = sizeof name
                end virtual
                purge struct?
        end macro
        esc macro struct?.name
end macro

macro struct?.container
        struct?.current
end macro

macro struct?.begin
        macro struct?.end
                purge struct?.end
                if struct?.subcounter >= 0
                        struct?.subcounter = struct?.subcounter + 1
                        repeat 1, j:struct?.subcounter
                                if struct?.counter >= 0
                                        struct?.counter = struct?.counter + 1
                                        repeat 1, i:struct?.counter
                                                match sub, struct?.substruct
                                                        define sub.__field#i __substruct#j
                                                else
                                                        define __field#i __substruct#j
                                                end match
                                        end repeat
                                end if
                                define struct?.substruct __substruct#j
                                define __substruct#j.__type substruct __substruct#j
                                struct?.counter =: 0
                        end repeat
                end if
                struct?.container
                if struct?.subcounter > 0
                        purge struct?.current
                        restore struct?.substruct,struct?.counter
                end if
        end macro
end macro

macro union?.begin
        local instance
        label instance
        macro struct?!
                struct?.begin
                esc macro struct?.current
        end macro
        macro struct?.end
                purge struct?.end
                macro struct?.container
                        instance !--
                end macro
                struc (field) ? def&
                        if $-instance = 0
                                match !--, def
                                        struct?.current
                                else
                                        field def
                                end match
                                if $-instance > 0
                                        struct?.counter =: -1
                                end if
                        else
                                virtual at instance
                                        match !--, def
                                                struct?.current
                                        else
                                                field def
                                        end match
                                        local size
                                        size = $-instance
                                end virtual
                                if size > $-instance
                                        rb size-($-instance)
                                end if
                        end if
                end struc
                union?.current
                restruc ?
                purge union?.current,struct?.container
                if $-instance > 0
                        restore struct?.counter
                end if
                purge struct?
        end macro
end macro

macro union?!
        union?.begin
        esc macro union?.current
end macro

macro ends?!
        esc end macro
        struct?.end
end macro

macro struct? definition
        match name base, definition
                macro struct?.launcher
                        purge struct?.launcher
                        struct name
                        struct?.base
                end macro
        else
                macro struct?.launcher
                        purge struct?.launcher
                        struct definition
                end macro
        end match
        struct?.launcher
end macro
    


After compilation we have error:
Code:
wc WNDCLASS style:0, lpfnWndProc:WindowProc, hbrBackground:COLOR_BTNFACE+1, lpszClassName:_class
macro WNDCLASS [5] macro init [3] macro init_field [24]:
          store value at .field
Processed:  store WindowProc  at . lpfnWndProc
Error:  variable term used  where not expected.
    


if I comment
Code:
...
wc WNDCLASS ;style:0, lpfnWndProc:WindowProc, hbrBackground:COLOR_BTNFACE+1, lpszClassName:_class
...    

or
Code:
...
;section '.reloc' fixups data readable discardable
...    

than all ok.
even so
Code:
wc WNDCLASS style:0, lpfnWndProc:WindowProc-PE.RELOCATION, hbrBackground:COLOR_BTNFACE+1, lpszClassName:_class-PE.RELOCATION    

all ok

struc.inc is crossCPU macroset hardcoding in it PE.RELOCATION looks ugly.
so there should be way to support struct in PE.inc own like that done for dword,qword etc.

Ability to skip relative to CPU-type relocation terms maybe should be in struct.inc.
But definition of term as CPU specific relocation again should be in PE.

_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 17 Jul 2017, 15:02
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8349
Location: Kraków, Poland
Tomasz Grysztar 17 Jul 2017, 16:06
This is something that PE.INC should handle, perhaps by overriding STORE.
Post 17 Jul 2017, 16:06
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8349
Location: Kraków, Poland
Tomasz Grysztar 17 Jul 2017, 19:45
Well, the above may be more appropriate in principle, but fixing this on the "struct" macros side is way easier, so I decided to add this alteration:
Code:
struc struct?.init_field name,field,value&
        match =struct type, name.field.__type
                .field struct?.init type,value
        else match =substruct type, name.field.__type
                . struct?.init name.type,value
        else match first=,rest, value
                local data
                virtual at 0
                        emit sizeof .field : value
                        load data : $ from 0
                end virtual
                if lengthof data <= name.field.__length
                        store data : lengthof data at .field
                else
                        err 'data too long for ',`name,'.',`field
                end if
        else if value eqtype ''
                if lengthof value <= name.field.__length
                        store value : lengthof value at .field
                else
                        err 'data too long for ',`name,'.',`field
                end if
        else if elementsof value
                local reduced
                virtual at .field
                        if sizeof .field = 4
                                dd value
                        else if sizeof .field = 8
                                dq value
                        else
                                dbx sizeof .field : value
                        end if
                        load reduced from .field
                end virtual
                store reduced at .field
        else
                store value at .field
        end if
end struc    
I updated the Windows macro package already.
Post 17 Jul 2017, 19:45
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.