title: How to create tiny PE (Win32) executables using MinGW
body: <p>I have the following C program:</p>
  
  <pre><code>#include &lt;windows.h&gt;
  void __cdecl mainCRTStartup() {
    DWORD bw;
    HANDLE hfile = GetStdHandle(STD_OUTPUT_HANDLE);
    WriteFile(hfile, "Hello, World!\r\n", 15, &amp;bw, 0);
    ExitProcess(0);  /* Needed for successful (0) exit. */
  }
  </code></pre>
  
  <p>I compile it with GCC 4.8.2, using the following command line:</p>
  
  <pre><code>i686-w64-mingw32-gcc -s -Os -fno-ident -fno-stack-protector -fomit-frame-pointer \
  -fno-unwind-tables -fno-asynchronous-unwind-tables -falign-functions=1  \
  -mpreferred-stack-boundary=2 -falign-jumps=1 -falign-loops=1 -mconsole \
  -nostdlib -nodefaultlibs -nostartfiles -o h.exe h.c -lkernel32
  </code></pre>
  
  <p>The generated .exe file is 2048 bytes long. How can I make it smaller using MinGW, preferably at most 1024 bytes, or (even better) at most 512 bytes?</p>
  
  <p>I'd prefer a solution without writing assembly code, but I'm also interested in assembly solutions.</p>
  
  <p>I've tried <code>-Wl,-N</code> to decrease the number of sections (segments), but that caused a segfault when running the .exe in Wine.</p>
  
  <p>This <a href="http://www.catch22.net/tuts/win32/reducing-executable-size" rel="nofollow noreferrer">article</a> suggests that 480 bytes is possible. It uses the following settings:</p>
  
  <pre><code>#pragma comment(linker, "/FILEALIGN:16")
  #pragma comment(linker, "/ALIGN:16")// Merge sections
  #pragma comment(linker, "/MERGE:.rdata=.data")
  #pragma comment(linker, "/MERGE:.text=.data")
  #pragma comment(linker, "/MERGE:.reloc=.data")
  #pragma optimize("gsy", on)
  </code></pre>
  
  <p>Unfortunately these <code>#pragma</code>s don't work with MinGW GCC. Are there equivalents?</p>
  
  <p>In <a href="http://www.independent-software.com/linking-a-flat-binary-from-c-with-mingw/" rel="nofollow noreferrer">here</a> I was able to find the GCC flags
  <code>-Wl,--section-alignment,16,--file-alignment,16</code> which bring down the .exe size to 752 bytes. The .exe seems to work in Wine.</p>
  
  <p>By <a href="https://gist.github.com/pts/9ef2b1036d0b42508327559eeb2e0eb5" rel="nofollow noreferrer">modifying the linker script</a> I was able to merge <code>.data</code> and <code>.rdata</code>, and go down to 736 bytes. I'm using these GCC flags in addition to those above: <code>-Wl,--section-alignment,16,--file-alignment,16,-T,tinygccpe.scr</code>.</p>
  
  <p>I'm still looking for the MinGW equivalent of <code>/MERGE</code>.</p>
  
  <p><a href="https://stackoverflow.com/questions/7973274/how-to-reduce-the-size-of-executable-produced-by-mingw-g-compiler">This question</a> is similar, but it doesn't attempt to go below 9000 bytes.</p>
  
  <p>I'm also looking for a <code>strip</code> tool (the <code>strip</code> command in MinGW doesn't reduce the .exe size any further) which can remove the DOS stub (which is between offsets 0x40 and 0x80, it contains <code>This program cannot be run in DOS mode.</code>, we could save 64 bytes). <a href="http://www.nirsoft.net/kernel_struct/vista/IMAGE_DOS_HEADER.html" rel="nofollow noreferrer">This code</a> can remove it, but it also breaks all the absolute offsets in the .exe. Unfortunately the linker <code>ld</code> in MinGW isn't able to remove the DOS stub, it's hardcoded in the file <code>bfd/peXXigen.c</code>, just above the <code>NT_SIGNATURE</code>.</p>
  
  <p>Is it possible to strip more headers from the .exe, i.e. headers which the loader doesn't use?</p>