flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > import/export with a simple list of function names

Author
Thread Post new topic Reply to topic
insolor



Joined: 01 Apr 2011
Posts: 5
insolor 24 Sep 2013, 10:00
Good day!

I have a simple dll library, it's source code is hosted here: https://bitbucket.org/dfint/fake_ttf.dll/src/tip?at=default

In short, it's source code consists of four files: Fake_ttf.asm, sdl_ttf_funcs.inc, import_sdl_ttf.inc, export_sdl_ttf.inc

The main file, Fake_ttf.asm looks like this:
Code:
format PE GUI DLL

entry DllEntryPoint

include 'win32ax.inc'

section '.text' code readable executable

proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
    mov eax,TRUE
    ret
endp

include 'sdl_ttf_funcs.inc'

irp func, sdl_ttf_funcs {
if func in <TTF_RenderUNICODE_Blended, TTF_SizeUNICODE>
    proc func, _, pwcText
        cinvoke ChangeText, [pwcText]
        test eax, eax
        jz @f
        mov [pwcText], eax
    @@:
        leave
    endp
else
    func:
end if
    jmp dword [real_#func]
}

section '.idata' import data readable writeable

library sdl_ttf, 'Real_ttf.dll',\
        changetext, 'ChangeText.dll'

import changetext,\
        ChangeText, 'ChangeText'

include 'import_sdl_ttf.inc'

section '.edata' export data readable

include 'export_sdl_ttf.inc'

section '.reloc' fixups data discardable    


sdl_ttf_funcs.inc contains a simple list of functions:
Code:
sdl_ttf_funcs fix \
    TTF_ByteSwappedUNICODE, TTF_CloseFont, TTF_FontAscent, TTF_FontDescent,\
    TTF_FontFaceFamilyName, TTF_FontFaceIsFixedWidth, TTF_FontFaceStyleName,\
    TTF_FontFaces, TTF_FontHeight, TTF_FontLineSkip, TTF_GetFontHinting,\
    TTF_GetFontKerning, TTF_GetFontOutline, TTF_GetFontStyle,\
    TTF_GlyphIsProvided, TTF_GlyphMetrics, TTF_Init, TTF_Linked_Version,\
    TTF_OpenFont, TTF_OpenFontIndex, TTF_OpenFontIndexRW, TTF_OpenFontRW,\
    TTF_Quit, TTF_RenderGlyph_Blended, TTF_RenderGlyph_Shaded,\
    TTF_RenderGlyph_Solid, TTF_RenderText_Blended, TTF_RenderText_Shaded,\
    TTF_RenderText_Solid, TTF_RenderUNICODE_Blended, TTF_RenderUNICODE_Shaded,\
    TTF_RenderUNICODE_Solid, TTF_RenderUTF8_Blended, TTF_RenderUTF8_Shaded,\
    TTF_RenderUTF8_Solid, TTF_SetFontHinting, TTF_SetFontKerning,\
    TTF_SetFontOutline, TTF_SetFontStyle, TTF_SizeText, TTF_SizeUNICODE,\
    TTF_SizeUTF8, TTF_WasInit    

import_sdl_ttf.inc contains these functions imported with 'real_' prefix:
Code:
import sdl_ttf,\
    real_TTF_ByteSwappedUNICODE, 'TTF_ByteSwappedUNICODE',\
    real_TTF_CloseFont, 'TTF_CloseFont',\
    real_TTF_FontAscent, 'TTF_FontAscent',\
    ...
    real_TTF_SizeUNICODE, 'TTF_SizeUNICODE',\
    real_TTF_SizeUTF8, 'TTF_SizeUTF8',\
    real_TTF_WasInit, 'TTF_WasInit'    

In turn export_sdl_ttf.inc contains these functions exported:
Code:
export 'SDL_ttf.dll',\
    TTF_ByteSwappedUNICODE, 'TTF_ByteSwappedUNICODE',\
    TTF_CloseFont, 'TTF_CloseFont',\
    TTF_FontAscent, 'TTF_FontAscent',\
    ...
    TTF_SizeUNICODE, 'TTF_SizeUNICODE',\
    TTF_SizeUTF8, 'TTF_SizeUTF8',\
    TTF_WasInit, 'TTF_WasInit'    
I want to make some macros for import and export to avoid triple replication of function list, something like this:
Code:
my_import sdl_ttf, real_, sdl_ttf_funcs
my_export 'SDL_ttf', sdl_ttf_funcs    
Is this possible with wrapping import/export into another macros, without reinventing of import/export itself?
Post 24 Sep 2013, 10:00
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 24 Sep 2013, 13:18
insolor
What you do seems to be a proxy dll. You can make it without specifying the complete list of functions. See an example here for that. A little newer version is attached here, but I didn't have time to update it to the newer fasm capabilities. Thus it's a little laggy for target dll's with a large export table.


Description:
Download
Filename: forwardedexport.zip
Filesize: 2.25 KB
Downloaded: 413 Time(s)


_________________
Faith is a superposition of knowledge and fallacy
Post 24 Sep 2013, 13:18
View user's profile Send private message Reply with quote
insolor



Joined: 01 Apr 2011
Posts: 5
insolor 24 Sep 2013, 19:38
Indeed, it's a proxy dll, but before I haven't known how do such things are called Smile

As for your utility, I'd better extract the complete list of functions with some separate tool and then include this list. It's just my own seeing of the problem. I am just intending to simplify the code of my lib. May be I will consider to leave the currently existing code as is.
Post 24 Sep 2013, 19:38
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 24 Sep 2013, 20:55
insolor
I don't second your vision of the problem for multiple reasons, but the main one is that you mix payload with directives. The code becomes very hard to understand. Therefore such things must generally be avoided:
Quote:
Code:
irp func, sdl_ttf_funcs {
if func in <TTF_RenderUNICODE_Blended, TTF_SizeUNICODE>
    proc func, _, pwcText
        cinvoke ChangeText, [pwcText]
        test eax, eax
        jz @f
        mov [pwcText], eax
    @@:
        leave
    endp
else
    func:
end if
    jmp dword [real_#func]
}    

My solution in turn is completely separated and abstracted from the payload.

Anyway, here's a simple solution within the framework of your vision:
Code:
macro myexport name*,funclist*
{
    match funcs,funclist \{ irp func,funcs \\{ define func func,\\`func \\} \}
    match funcs,funclist \{ match list,funcs \\{
        restore funcs
        export name,list
    \\} \}
}
macro myimport name*,prefix*,funclist*
{
    match funcs,funclist \{ irp func,funcs \\{ define func prefix\\#func,\\`func \\} \}
    match funcs,funclist \{ match list,funcs \\{
        restore funcs
        import name,list
    \\} \}
}    

It assumes, that you use sdl_ttf_funcs equ ... instead of sdl_ttf_funcs fix ... . Never use fix unless there's no other way to go, which can only happen if you need to override a preprocessor directive.

P.S. Here's a little more conventional version:
Code:
macro myexport name*,funclist*
{
    match funcs,funclist \{ irp func,funcs
    \\{
        \\forward \\local newlist
            define newlist func,\\`func
        \\common
            match list,newlist \\\{ export name,list \\\}
            restore newlist
    \\} \}
}
macro myimport name*,prefix*,funclist*
{
    match funcs,funclist \{ irp func,funcs
    \\{
        \\forward \\local newlist
            define newlist prefix\\#func,\\`func
        \\common
            match list,newlist \\\{ import name,list \\\}
            restore newlist
    \\} \}
}    

_________________
Faith is a superposition of knowledge and fallacy
Post 24 Sep 2013, 20:55
View user's profile Send private message Reply with quote
insolor



Joined: 01 Apr 2011
Posts: 5
insolor 25 Sep 2013, 06:53
Quote:
Never use fix unless there's no other way to go, which can only happen if you need to override a preprocessor directive.
Thank you for your advice. Unfortunately, my irp func, sdl_ttf_funcs { ... works only with sdl_ttf_funcs fix .... Probably I am doing something in a wrong way.

Another thing, I cannot find information about an asterisk in the macro declaration (macro myexport name*,funclist*) in the flat assembler Programmer's Manual. Can you point me, were can I read about it?
Post 25 Sep 2013, 06:53
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 25 Sep 2013, 09:41
insolor
Quote:
Unfortunately, my irp func, sdl_ttf_funcs { ... works only with sdl_ttf_funcs fix ...

That's because irp takes a list to enumerate through. When you use fix, it's expanded before any further preprocessing is done, and this way irp gets a list instead of the single value sdl_ttf_funcs . When you use equ or define you cannot pass sdl_ttf_funcs, because it won't be automatically expanded. Instead you must explicitly expand sdl_ttf_funcs into a list using the match directive as I've shown you in the myimport and myexport macros. This way irp will again never see the single value sdl_ttf_funcs.

Quote:
Can you point me, were can I read about it?

Look here:
2.3.3 Macroinstructions wrote:
By placing the * after the name of argument you can mark the argument as required - preprocessor will not allow it to have an empty value. For example the above macroinstruction could be declared as macro mov op1*,op2*,op3 to make sure that first two arguments will always have to be given some non empty values.

_________________
Faith is a superposition of knowledge and fallacy
Post 25 Sep 2013, 09:41
View user's profile Send private message Reply with quote
insolor



Joined: 01 Apr 2011
Posts: 5
insolor 25 Sep 2013, 12:48
Thank you for the explanation, now all has become much clearer.
Post 25 Sep 2013, 12:48
View user's profile Send private message 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.