[llvm-dev] trying to get a minimal windows program linked with lld

Andrew Kelley via llvm-dev llvm-dev at lists.llvm.org
Sun Jun 4 12:33:52 PDT 2017


Here's some C code:

extern void *GetStdHandle(unsigned int nStdHandle);
extern void ExitProcess(unsigned int exit_code);
extern char WriteFile(void *HANDLE, const void * lpBuffer, unsigned int
nNumberOfBytesToWrite,
    unsigned int *lpNumberOfBytesWritten, void *lpOverlapped);

static const char *message_ptr = "hello\n";
static const unsigned int message_len = 6;

__attribute__((stdcall)) int _start(void) {
    void *hStdOut = GetStdHandle(-11);
    WriteFile(hStdOut, message_ptr, message_len, 0, 0);
    ExitProcess(0);
}


I use mingw-w64 like this:

gcc -c test.c


Create kernel32.def:

EXPORTS
ExitProcess
GetStdHandle
WriteFile


Use dlltool to create kernel32.lib:

dlltool -d kernel32.def -l kernel32.lib


Then link with lld-link:

lld-link -NOLOGO -SUBSYSTEM:console test.o kernel32.lib  -OUT:test.exe
-NODEFAULTLIB -ENTRY:_start

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
    140005068:   ff 25 ce cf ff ff       jmpq   *-0x3032(%rip)        #
0x14000203c
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.

Any ideas how to make these library calls hook up correctly?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170604/9954c764/attachment.html>


More information about the llvm-dev mailing list