<div dir="ltr">Hi Andrew,<div><br></div><div>Are you using the release version of LLD 4.0 or the SVN head? I recently made a change to the import table structure after the 4.0 release, and I'm wondering if it caused the issue.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jun 4, 2017 at 2:50 PM, Shoaib Meenai <span dir="ltr"><<a href="mailto:smeenai@fb.com" target="_blank">smeenai@fb.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Oops; I forgot that attachments wouldn't work. <a href="https://www.dropbox.com/s/jrdbljl1q1nv5dy/kernel32.lib?dl=1" rel="noreferrer" target="_blank">https://www.dropbox.com/s/<wbr>jrdbljl1q1nv5dy/kernel32.lib?<wbr>dl=1</a><br>
<div class="HOEnZb"><div class="h5"><br>
On 6/4/17, 2:46 PM, "llvm-dev on behalf of Shoaib Meenai via llvm-dev" <<a href="mailto:llvm-dev-bounces@lists.llvm.org">llvm-dev-bounces@lists.llvm.<wbr>org</a> on behalf of <a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br>
<br>
+ruiu and compnerd, since there might be an lld issue here.<br>
<br>
A slightly simpler example. This is all x86_64; I haven't tried x86.<br>
<br>
% cat imp.c<br>
__declspec(dllimport) void ExitProcess(unsigned exitCode);<br>
int mainCRTStartup() { ExitProcess(0); }<br>
<br>
% cat kernel32.def<br>
LIBRARY kernel32<br>
EXPORTS<br>
ExitProcess<br>
<br>
% dlltool –d kernel32.def –l kernel32.lib<br>
% cl /Zl /c imp.c<br>
% link /subsystem:console imp.obj kernel32.lib<br>
<br>
The above executable runs successfully, as does one compiled with ld:<br>
% ld --version<br>
GNU ld (GNU Binutils) 2.28<br>
% ld imp.obj kernel32.lib<br>
<br>
If we compile with lld, however:<br>
% lld-link /subsystem:console /entry:mainCRTStartup imp.obj kernel32.lib<br>
<br>
The resulting executable segfaults, and it doesn't actually have any imports:<br>
% llvm-readobj -coff-imports imp.exe<br>
File: imp.exe<br>
Format: COFF-x86-64<br>
Arch: x86_64<br>
AddressSize: 64bit<br>
<br>
Given that both link.exe and MinGW-w64's ld are able to handle the import<br>
library correctly, I'm inclined to believe this is an issue with lld. I'm<br>
attaching the kernel32.lib output by dlltool for ease of investigation.<br>
<br>
From: llvm-dev <<a href="mailto:llvm-dev-bounces@lists.llvm.org">llvm-dev-bounces@lists.llvm.<wbr>org</a>> on behalf of Andrew Kelley via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>><br>
Reply-To: Andrew Kelley <<a href="mailto:superjoe30@gmail.com">superjoe30@gmail.com</a>><br>
Date: Sunday, June 4, 2017 at 1:15 PM<br>
To: LLVM Dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>><br>
Subject: Re: [llvm-dev] trying to get a minimal windows program linked with lld<br>
<br>
Update: smeenai from #llvm has been helping me with this, and we narrowed it down to kernel32.lib being no good. kernel32.lib from the 14393 SDK worked fine.<br>
<br>
My goal is to not depend on .lib files from the SDK, so there's still a problem to solve here.<br>
<br>
On Sun, Jun 4, 2017 at 3:33 PM, Andrew Kelley <<a href="mailto:superjoe30@gmail.com">superjoe30@gmail.com</a>> wrote:<br>
Here's some C code:<br>
<br>
extern void *GetStdHandle(unsigned int nStdHandle);<br>
extern void ExitProcess(unsigned int exit_code);<br>
extern char WriteFile(void *HANDLE, const void * lpBuffer, unsigned int nNumberOfBytesToWrite,<br>
unsigned int *lpNumberOfBytesWritten, void *lpOverlapped);<br>
<br>
static const char *message_ptr = "hello\n";<br>
static const unsigned int message_len = 6;<br>
<br>
__attribute__((stdcall)) int _start(void) {<br>
void *hStdOut = GetStdHandle(-11);<br>
WriteFile(hStdOut, message_ptr, message_len, 0, 0);<br>
ExitProcess(0);<br>
}<br>
<br>
<br>
I use mingw-w64 like this:<br>
<br>
gcc -c test.c<br>
<br>
<br>
Create kernel32.def:<br>
<br>
EXPORTS<br>
ExitProcess<br>
GetStdHandle<br>
WriteFile<br>
<br>
<br>
Use dlltool to create kernel32.lib:<br>
<br>
dlltool -d kernel32.def -l kernel32.lib<br>
<br>
<br>
Then link with lld-link:<br>
<br>
lld-link -NOLOGO -SUBSYSTEM:console test.o kernel32.lib -OUT:test.exe -NODEFAULTLIB -ENTRY:_start<br>
<br>
This succeeds, but then I get a segfault when running test.exe. When I step through the code, what's happening is it's getting to<br>
140005068: ff 25 ce cf ff ff jmpq *-0x3032(%rip) # 0x14000203c<br>
which is trying to jump into .idata section where presumably the stub for GetStdHandle lives. However after this jump, $rip ends up getting assigned a bogus address and then the segfault happens.<br>
<br>
Any ideas how to make these library calls hook up correctly?<br>
<br>
<br>
<br>
<br>
<br>
<br>
</div></div></blockquote></div><br></div>