www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - LDC lto generate wrong dll export table

reply Test123 <test123 gmail.com> writes:
The problem is when link with LDC generate lto object, there is 
no export table name.

ldmd2 -mtriple=x86_64-w64-mingw32 -betterC  -flto=full -c ./test.d

```d
import ldc.attributes : assumeUsed;
import core.sys.windows.windows;
 nogc nothrow extern(C):
export int test()  assumeUsed {
         return 0;
}

export extern(Windows) BOOL DllMain(HINSTANCE hInstance, ULONG 
ulReason, LPVOID pvReserved)  assumeUsed {
         return true;
}
```

x86_64-w64-mingw32-clang -flto=full ./test.c -c

```c
#include <windows.h>

BOOL WINAPI DllMain(HINSTANCE hinst,DWORD reason,LPVOID 
lpReserved)
{
	return TRUE;
}

__declspec(dllexport) int test(){
	return 0;
}
```

to link with lld (or use clang -L/dll -shared)

```sh
lld -flavor ld -lmsvcrt -m i386pep --shared -Bdynamic -e 
DllMainCRTStartup --enable-auto-image-base -o test.dll 
mingw/x86_64-w64-mingw32/lib/dllcrt2.o 
mingw/x86_64-w64-mingw32/lib/crtbegin.o 
-Lmingw/x86_64-w64-mingw32/lib -Lmingw/lib 
-Lmingw/x86_64-w64-mingw32/sys-root/mingw/lib 
-Lmingw/lib/clang/14.0.0/lib/windows test.o -ldnsapi -lbcrypt 
-lpsapi -lole32 -liphlpapi -luserenv /dll -lws2_32 
-lssp_nonshared -lmingw32 
mingw/lib/clang/14.0.0/lib/windows/libclang_rt.builtins-x86_64.a 
-lmoldname -lmingwex -ladvapi32 -lshell32 -luser32 -lkernel32 
mingw/x86_64-w64-mingw32/lib/crtend.o -Bdynamic
```


As you can see, c and d code are same, and use same link 
argument. (I replace the test.o with link script to test)

If I build D code without LTO, I get the correct binary like 
clang dose.

Only when I build code with LDC and LTO, the problem exists:

Verify with x86_64-w64-mingw32-objdump --private-headers 
test.dll, you will see random symbol name for LDC & LDC 
bianry(some time empty).
May 22 2022
parent reply Test123 <test123 gmail.com> writes:
On Sunday, 22 May 2022 at 17:06:46 UTC, Test123 wrote:
 The problem is when link with LDC generate lto object, there is 
 no export table name.
to viery this please download https://github.com/mstorsjo/llvm-mingw/releases/download/20220323/llvm-mingw-20220323-msvcrt-ubuntu 18.04-x86_64.tar.xz into linux(there is also macOS and Windows version). test with clang: ```sh ./mingw/bin/x86_64-w64-mingw32-clang -flto=full ./test.c -c ./mingw/bin/lld -flavor ld -lmingwex -lmingw32 -lmsvcrt -lkernel32 -m i386pep --shared -Bdynamic test.o -o test.dll -e DllMainCRTStartup --enable-auto-image-base mingw/x86_64-w64-mingw32/lib/dllcrt2.o mingw/x86_64-w64-mingw32/lib/crtbegin.o -Lmingw/x86_64-w64-mingw32/lib -Lmingw/lib -Lmingw/x86_64-w64-mingw32/sys-root/mingw/lib -Lmingw/lib/clang/14.0.0/lib/windows /dll mingw/lib/clang/14.0.0/lib/windows/libclang_rt.builtins-x86_64.a mingw/x86_64-w64-mingw32/lib/crtend.o -Bdynamic ./mingw/bin/x86_64-w64-mingw32-objdump --private-headers ./test.dll ``` And you will see this at the end: ```sh Export Table: DLL name: test.dll Ordinal base: 0 Ordinal RVA Name 0 0 1 0x2350 test ``` verify with ldc ```sh ldmd2 -mtriple=x86_64-w64-mingw32 -betterC -flto=full -c ./test.d ./mingw/bin/lld -flavor ld -lmingwex -lmingw32 -lmsvcrt -lkernel32 -m i386pep --shared -Bdynamic test.o -o test.dll -e DllMainCRTStartup --enable-auto-image-base mingw/x86_64-w64-mingw32/lib/dllcrt2.o mingw/x86_64-w64-mingw32/lib/crtbegin.o -Lmingw/x86_64-w64-mingw32/lib -Lmingw/lib -Lmingw/x86_64-w64-mingw32/sys-root/mingw/lib -Lmingw/lib/clang/14.0.0/lib/windows /dll mingw/lib/clang/14.0.0/lib/windows/libclang_rt.builtins-x86_64.a mingw/x86_64-w64-mingw32/lib/crtend.o -Bdynamic ./mingw/bin/x86_64-w64-mingw32-objdump --private-headers ./test.dll ``` you will this this at the end: ```sh Export Table: DLL name: test.dll Ordinal base: 0 Ordinal RVA Name 0 0 1 0x2340 2 0x2330 t ``` The name for ldc2 wll be random(some time empty). Use ldc2 without LTO always give the same result like clang.
May 22 2022
parent reply Test123 <test123 gmail.com> writes:
On Sunday, 22 May 2022 at 17:27:28 UTC, Test123 wrote:
 Use ldc2 without LTO always give the same result like clang.
confirm with LDC 1.28.1, 1.30.0-beta1. When you have one short export symbol LDC unlikely generate wrong result, when there is more than one export it never generate right result. ```c #include <windows.h> __declspec(dllexport) int test1(){ return 0; } __declspec(dllexport) int test2(){ return 0; } ``` clang wlways generate correct test.dll. LDC give wrong result when more than one export is used with LTO: ```d import ldc.attributes : assumeUsed; export extern(C) int test1() assumeUsed { return 0; } export extern(C) int test2() assumeUsed { return 0; } ``` remove test1 or test2 will give you right result with LTO. but if you use a long function name like test111242342343243243, ldc will alway give wrong result with LTO.
May 22 2022
parent reply Test123 <test123 gmail.com> writes:
On Sunday, 22 May 2022 at 17:50:49 UTC, Test123 wrote:
 Use ldc2 without LTO always give the same result like clang.
I find a workaround, use ldc --output-ll generate ll file, then use clang build ll into object file with LTO, will fix the problem.
May 22 2022
parent reply Test123 <test123 gmail.com> writes:
On Sunday, 22 May 2022 at 18:17:45 UTC, Test123 wrote:
 On Sunday, 22 May 2022 at 17:50:49 UTC, Test123 wrote:
 Use ldc2 without LTO always give the same result like clang.
I find a workaround, use ldc --output-ll generate ll file, then use clang build ll into object file with LTO, will fix the problem.
Sadlly this will not work for a big project, cause some symbol not find problem. (not sure why) I hope this can be fixed ASAP with the information I provide. any suggestion will be much appreciated.
May 22 2022
parent kinke <noone nowhere.com> writes:
On Sunday, 22 May 2022 at 19:54:33 UTC, Test123 wrote:
 I hope this can be fixed ASAP with the information I provide.
Nope - MinGW isn't a supported target. Your example works fine when using the (default) MSVC target.
May 23 2022