wine can't load my custom build-in dll and report “call to unimplemented function”

匿名 (未验证) 提交于 2019-12-03 01:40:02

问题:

I can't login WINEHQ Bugzilla, so I ask here and this is the requirement:
We have a windows app which we have exe source code, and it used ATL. The dlls the exe depends require some special device, but mostly they have linux version. Now we need to port the windows app to linux.
My finally try: write a middle dll to wrap some lib which already is cross platform, the exe will call new middle dll, and I name the middle dll is "WINE custom build-in dll". CUSTOM means I compile this dll.so standalone by winemaker. Everything is fine until run it under wine64, the command line in linux shell:

wine64 portsome.exe 

here is the output:

wine: Call from 0x7bc5eeec to unimplemented function  wrapsome.dll.wrap_SOME_GetVersion, aborting Backtrace: =>0 0x000000007bc5eeec stub_entry_point+0x5c(dll=<is not available>, name=<is not available>, ret_addr=<is not available>) [/home/root0/src/wine/build/dlls/ntdll/../../../src/dlls/ntdll/loader.c:215] in ntdll (0x000000000023fbc0)     1 0x0000000140001022 in portsome (+0x1021) (0x000000000023fbc0)     2 0x00000001400012e2 in portsome (+0x12e1) (0x000000000023fd70)     3 0x000000007b47d02f start_process+0xbe(entry=0x140001418)  Modules: Module  Address                                 Debug info      Name (23 modules) ELF             7b400000-        7b81a000       Dwarf           kernel32<elf>   \-PE          7b420000-        7b81a000       \               kernel32 ELF             7bc00000-        7bd21000       Dwarf           ntdll<elf>   \-PE          7bc20000-        7bd21000       \               ntdll ELF             7c000000-        7c004000       Deferred        <wine-loader> PE             140000000-       140007000       Export          portsome ELF         7fbfe53b4000-    7fbfe56c6000       Deferred        msvcr100<elf>   \-PE      7fbfe53e0000-    7fbfe56c6000       \               msvcr100 ELF         7fbfe5b48000-    7fbfe5f1d000       Deferred        libhwaware.so ELF         7fbfe5f1d000-    7fbfe6131000       Deferred        wrapsome<elf>   \-PE      7fbfe5f20000-    7fbfe6131000       \               wrapsome ELF         7fbfe66bc000-    7fbfe68ce000       Deferred        libnss_files.so.2 ELF         7fbfe68ce000-    7fbfe6ada000       Deferred        libnss_nis.so.2 ELF         7fbfe6ada000-    7fbfe6cf3000       Deferred        libnsl.so.1 ELF         7fbfe6cf3000-    7fbfe6efc000       Deferred        libnss_compat.so.2 ELF         7fbfe70fc000-    7fbfe7312000       Deferred        libgcc_s.so.1 ELF         7fbfe7312000-    7fbfe761b000       Deferred        libm.so.6 ELF         7fbfe761e000-    7fbfe7822000       Deferred        libdl.so.2 ELF         7fbfe7822000-    7fbfe7bec000       Deferred        libc.so.6 ELF         7fbfe7bed000-    7fbfe7e0a000       Deferred        libpthread.so.0 ELF         7fbfe7e22000-    7fbfe81c8000       Dwarf           libwine.so.1 ELF         7fbfe81ca000-    7fbfe83f2000       Deferred        ld-linux-x86-64.so.2 ELF         7ffd8bbe1000-    7ffd8bbe2000       Deferred        [vdso].so 

Here is my question:
how do I compile a wine custom build-in dll to make windows native app can call its function when running, is it need to generate a fake dll by winebuilder?

Detail steps I working for port windows app to linux:
1. find the special dll which need contact with hardware directly, like CUDA, dongle access.
2. make a wrap dll, change the exe code to call this wrap dll function, and the wrap dll then call hardware aware dll.
3. create "wrapsome.spec" file with https://wiki.winehq.org/Winelib_User%27s_Guide#The_Spec_file requirements.
4. copy the wrap code to Ubuntu 16.04, switch to wrap code source directory and run below command in shell:

winemaker --dll --nosource-fix -DWRAPSOME_EXPORTS -I../deps/hdaware -L../deps/hdaware -lhdaware . 

then I got the "Makefile" file and I append -fPIC to LDFLAGS.
5. continue to run "make", yea, I got the wrapsome.dll.so, and I copy it to wine build-in dlls directory. 6. finally I failed to run "wine64 portsome.exe", the question is mentioned above.
wine report "unimplemented function wrapsome.dll.wrap_SOME_GetVersion", I even confirmed with nm wrapsome.dll.so, and here is its output:

0000000000213291 B __bss_start 0000000000213298 b call_fini.9485 0000000000213294 b completed.7585                  w __cxa_finalize 00000000000118b0 t deregister_tm_clones 0000000000011a20 t DisableThreadLibraryCalls 0000000000011bf0 t DllMain 0000000000011940 t __do_global_dtors_aux 0000000000212de8 t __do_global_dtors_aux_fini_array_entry 0000000000213040 d __dso_handle 0000000000212df8 d _DYNAMIC 0000000000213291 D _edata 00000000002132a0 B _end 0000000000011c88 t _fini 0000000000011980 t frame_dummy 0000000000212de0 t __frame_dummy_init_array_entry 0000000000011ec8 r __FRAME_END__ 0000000000213000 d _GLOBAL_OFFSET_TABLE_                  w __gmon_start__ 0000000000011cb8 r __GNU_EH_FRAME_HDR 0000000000000810 t _init                  w _ITM_deregisterTMCloneTable                  w _ITM_registerTMCloneTable 0000000000212df0 d __JCR_END__ 0000000000212df0 d __JCR_LIST__                  w _Jv_RegisterClasses 00000000000118f0 t register_tm_clones                  U SOME_GetVersion                  U SOME_InitAwareSDK                  U SOME_UninitAwareSDK 0000000000213298 d __TMC_END__                  U __wine_dll_register@@WINE_1.0                  U __wine_main_argc@@WINE_1.0                  U __wine_main_argv@@WINE_1.0 0000000000011ad0 t __wine_spec_dll_entry 0000000000011c94 r __wine_spec_file_name 0000000000011a20 t __wine_spec_import_thunks 0000000000011c20 t __wine_spec_init 0000000000011c40 t __wine_spec_init_ctor 000000000021329c b __wine_spec_init_state 0000000000213048 d __wine_spec_nt_header 000000000000082a t __wine_spec_pe_header 00000000000119b0 t __wine_spec_relay_entry_points 0000000000011ab9 T wrap_SOME_GetVersion 0000000000011a3c T wrap_SOME_InitAwareSDK 0000000000011a53 T wrap_SOME_UninitAwareSDK 0000000000011a26 T _Z7DllMainP11HINSTANCE__jPv 

Notice: I have dismissed some word with common ones as it is not good to show to the public.

I even read the wine source code in github https://github.com/wine-mirror/wine/blob/fdac39f697e049ead215b164bfe6953269ffa7be/dlls/ntdll/loader.c#L660, it seems
exports = RtlImageDirectoryEntryToData( imp_mod, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size ); can't export the warpsome.dll.so file symbol table which I compile by winemaker+winegcc tool chain.

回答1:

I changed the wrapsome.spec file to this content:

@ stdcall wrap_SOME_InitAwareSDK(ptr) wrap_SOME_InitAwareSDK @ stdcall wrap_SOME_UninitAwareSDK(ptr) wrap_SOME_UninitAwareSDK @ stdcall wrap_SOME_GetVersion() wrap_SOME_GetVersion 

and make again, then cp to wine dlls directory, it works! And I known there is no need to change the exe link to warp dll in windows, just build a dll.so with extract the same export name which need by exe, it should works too. I will try it later.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!