FIXED statement in EXP for 4% smaller EXE without .reloc table

In your EXE Global Embed “Creating the Export file” add a line with just “FIXED” and the Linker will not generate a Relocation section (.reloc) making the EXE smaller. The link will probably run a tiny bit faster. The EXE is loaded first and is never** relocated. Do NOT use for DLLs.

I tried it in DLLTutor and the EXE shrunk by only 1024 bytes. DumpBin verified the .reloc was gone. So I added it to some projects with big (too big) EXEs and see average 4% reduction in size:


Copy/Paste below into Global Embed: Creating the Export File
FIXED ; remove .reloc table … only use on EXE

FIXED is a common feature of Windows Linkers like the VS C++.

When /FIXED is specified, LINK does not generate a relocation section in the program. At run time, if the operating system is unable to load the program at the specified address, it issues an error message and does not load the program.

In An In-Depth Look into the Win32 Portable Executable File Format, Part 2
See section on “Base Relocations”

In Visual C++ 6.0, the linker omits relocations for EXEs when doing a release build. This is because EXEs are the first thing brought into an address space, and therefore are essentially guaranteed to load at the preferred load address. DLLs aren’t so lucky, so base relocations should always be left in, unless you have a reason to omit them with the /FIXED switch. In Visual Studio .NET, the linker omits base relocations for debug and release mode EXE files.

This article was from 2002. I am sure this has changed due to ASLR. I found it reassuring that FIXED used to be the norm for EXEs.

** ASLR can relocate EXEs but will NOT if FIXED is used. If you’ve figured out how to enable DYNAMICBASE you probably know this. ASLR = “Address Space Layout Randomization” a new security feature added in Vista.

I found FIXED looking at the strings in the Linker ClaLPE.DLL for undocumented stuff …

I also see ISOLATION_AWARE which I have not tried to make work, just did some Googling. I think it might be related to ISOLATIONAWARE_MANIFEST_RESOURCE_ID which allows a DLL to have its own MANIFEST that is different than the EXE (Application) MANIFEST.

E.g. Some code I work on has Visual Styles turned OFF in most EXEs. This may allow one DLL to have a MANIFEST to turn Styles ON so it can use the new v6 Common Controls DLL that has the new TaskDialog().

ISOLATIONAWARE_MANIFEST_RESOURCE_ID is used primarily for DLLs. It should be used if the dll wants private dependencies other than the process default. For example, if an dll depends on comctl32.dll version It should have a resource of type RT_MANIFEST, ID ISOLATIONAWARE_MANIFEST_RESOURCE_ID to depend on comctl32.dll version, so that even if the process executable wants comctl32.dll version 5.1, the dll itself will still use the right version of comctl32.dll.

When LoadLibrary is called, before loading the dependencies of the dll, the NT library loader checks to see if the dll has a resource of type RT_MANIFEST, ID ISOLATIONAWARE_MANIFEST_RESOURCE_ID. If it does, the loader calls CreateActCtx with the resource, and use the generated activation context to probe the dll’s static dependencies. This is reason why the dll can have private dependencies with the ISOLATIONAWARE_MANIFEST_RESOURCE_ID resource.

1 Like

Not quiet relate to this interesting article but of a similar nature. How does one get a Clarion DLL to manifest the V6 common controls DLL when called from a DOT NET csharp program. Every time i call the clarion DLL via invoke the clarion DLL does not use the Manifested dialogs and loses it styling and flat look and feel.

Start a new thread. Include screen captures. Note (or paste) your EXE Manifest