<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>