boostorg / dll

Library for comfortable work with DLL and DSO
https://boost.org/libs/dll
52 stars 43 forks source link

bad codegen with visual studio 16.5 #39

Closed BurningEnlightenment closed 4 years ago

BurningEnlightenment commented 4 years ago

~The "Importing a C function from windows dll" example currently leads to bogus assembly generation with visual studio 16.5.~

I refactored the code a bit to get an easily digestible assembly snippet, ~but the issue can also be reproduced with the code from the example copied verbatim~ _and made GetStdHandlet a goddamn pointer.

using GetStdHandle_t =  void *(__stdcall *)(unsigned int);
namespace dll = boost::dll;

struct stable_layout
{
    dll::shared_library lib;
    GetStdHandle_t getStdHandle;

    stable_layout()
        : lib("Kernel32.dll", dll::load_mode::search_system_folders)
        , getStdHandle(nullptr)
    {}
};

void func_lookup(stable_layout &self)
{
    self.getStdHandle = self.lib.get<GetStdHandle_t>("GetStdHandle");
}

if compiled with cl /I..\boost\include /DBOOST_DLL_USE_STD_FS=1 /std:c++17 /EHsc /Zi x.cpp func_lookup will be lowered to the following x86 assembly:

push    ebp
mov     ebp,esp
push    ecx
mov     eax,dword ptr ss:[ebp+0x8]  ; [ebp+0x8]: "self" parameter on stack
mov     dword ptr ss:[ebp-0x4],eax
push    x.5A9E50                    ; 5A9E50: "GetStdHandle"
mov     ecx,dword ptr ss:[ebp-0x4]
call    x.543BFC                    ; 543BFC: shared_library::get
                                    ; function address is returned in eax
mov     ecx,dword ptr ss:[ebp+0x8]
mov     edx,dword ptr ds:[eax]      ; dereference of eax/function address
mov     dword ptr ds:[ecx+0x4],edx  ; [ecx+0x4]: self.getStdHandle
mov     esp,ebp
pop     ebp
ret

The lowered x64 assembly is also borked. Boost version 1.72; x.cpp. MS DevCom Ticket

BurningEnlightenment commented 4 years ago

Nevermind. I somehow completely missed the fact that shared_library::get doesn't work with function pointer types. I'm sorry for the noise.