1

I am using MSVC 2019. I have compiled a simple C++ code (Hello World...). When I compile it in release mode in x86 architecture, there is a .reloc section, but when I compile it in x64 architecture, the .reloc section does not exist.

What is the reason of this? I need executables with a .reloc section.

Best regards.

EDIT - 1:

C/C++ Settigs:

/permissive- /GS- /GL /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl /Fd"x64\Release\vc142.pdb" /Zc:inline /fp:precise /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oi /MT /FC /Fa"x64\Release\" /EHsc /nologo /Fo"x64\Release\" /Fp"x64\Release\test-reloc.pch" /diagnostics:column

Linker Settings:

/OUT:"F:\Test\x64\Release\test-reloc.exe" /MANIFEST:NO /LTCG:incremental /NXCOMPAT /PDB:"F:\Test\x64\Release\test-reloc.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /FIXED:NO /MACHINE:X64 /ENTRY:"relocMain" /OPT:REF /SAFESEH:NO /INCREMENTAL:NO /PGD:"F:\Test\x64\Release\test-reloc.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:NO /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /NODEFAULTLIB /TLBID:1

fortyEight
  • 23
  • 4
  • 2
    Too little familiarity with this, but [perhaps `/DYNAMICBASE`](https://learn.microsoft.com/en-us/cpp/build/reference/dynamicbase-use-address-space-layout-randomization?view=vs-2019) can force it. – user4581301 Oct 28 '20 at 23:45
  • The default Hello World generated by VC++ 2019 has a `.reloc` section in the x64 build. It becomes no longer necessary if you explicitly override the default linker setting with `/DYNAMICBASE:NO`. – dxiv Oct 29 '20 at 03:57
  • User4581301 and Dxiv thank you for your suggestions but I already set DYNAMICBASE option. I updated my question for adding linker settings. – fortyEight Oct 29 '20 at 19:05
  • @fortyEight If those are the actual command lines they could really use some cleanup. There are conflicting options (`/MANIFESTUAC`, `MANIFEST:NO`), overlapping ones (`/sdl-`, `/GS-`), deprecated (`/pgd`) and/or missing (`/ltcg`) etc. – dxiv Oct 30 '20 at 02:28
  • @fortyEight Also, you should specify in the question that the "*simple C++ code*" is actually handcrafted to avoid the standard C/C++ libraries, and does not use or link to the CRT. – dxiv Oct 30 '20 at 02:33

1 Answers1

3

The question is about the PE layout generated by MSVC in x64 builds. Leaving out details that are not relevant, it can be restated in plain C as follows.

// main.c

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

int __stdcall rawMain()
{
    OutputDebugStringA("Hello World!\n");
    return 0;
}

The minimalistic C program above, built without using or linking to the CRT, has no .reloc section in the x64 compile.

X:\etc>cl /nologo main.c /GS- /O2 /link /nodefaultlib kernel32.lib /manifest:no /subsystem:console /machine:x64 /entry:rawMain
main.c

X:\etc>dumpbin /nologo main.exe

Dump of file main.exe

File Type: EXECUTABLE IMAGE

  Summary

        1000 .pdata
        1000 .rdata
        1000 .text

X:\etc>

What is the reason of this?

Reason is that the generated code has no relocations, and therefore no .reloc section is created because "Windows will refuse to load a DLL (or EXE) if has an empty section" - as quoted from the answer to How to use the fixups attribute on a section? on SO, with a reference to the dll in fasm (bug?!) thread on the fasm board.

If a .reloc section is absolutely desired, the easiest way is to force a relocatable symbol in the code. For example, the following is enough to make it happen.

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

static void (*foo)(LPCSTR) = OutputDebugStringA;

int __stdcall rawMain()
{
    foo("Hello World!\n");
    return 0;
}
X:\etc>cl /nologo main.c /GS- /O2 /link /nodefaultlib kernel32.lib /manifest:no /subsystem:console /machine:x64 /entry:rawMain
main.c

X:\etc>dumpbin /nologo /relocations main.exe

Dump of file main.exe

File Type: EXECUTABLE IMAGE

BASE RELOCATIONS #5
    3000 RVA,        C SizeOfBlock
       0  DIR64      0000000140001018
       0  ABS

  Summary

        1000 .data
        1000 .pdata
        1000 .rdata
        1000 .reloc
        1000 .text

X:\etc>
dxiv
  • 16,984
  • 2
  • 27
  • 49