Convert to unix line endings.
[wincetools.git] / loader / README
index 847af0c..7167b24 100644 (file)
-HiMemCE\r
-=======\r
-\r
-HiMemCE is a high memory loader for Windows CE.  It softens the 32 MB\r
-process limit by allowing the EXE to load in the large file area\r
-reserved for file mappings.  This way, the EXE can be as large as free\r
-unfragmented virtual memory in that region, or free physical memory\r
-(whatever is smaller).  By linking libraries statically to the\r
-program, problems with too large or too many DLLs can be avoided.\r
-\r
-The usage of the loader is very simple.\r
-\r
-1. First, the program to be loaded has to be linked with the option\r
-/FIXED:NO (in MSVS, this setting can be found under Properties,\r
-Configuration Properties, Linker, Advanced, Fixed Base Address, choose\r
-"Generate a relocation section").  Here is a CMake example:\r
-\r
-SET_TARGET_PROPERTIES(foo PROPERTIES LINK_FLAGS " /FIXED:NO")\r
-\r
-2. Install the program "foo" under foo-real.exe, and copy the loader's\r
-himemce.exe side-by-side to it as foo.exe.  Then the loader (as\r
-foo.exe) transparently proxies all start ups of the foo program.  It\r
-will automatically look for foo-real.exe and load that into high\r
-memory, continueing execution there.\r
-\r
-Contained in this package is a himemce-real.exe, that serves as an\r
-example/test program.  In the special case of "himemce.exe", verbose\r
-output is on by default.\r
-\r
-How it works\r
-------------\r
-\r
-HiMemCE allocates a virtual memory region with VirtulAlloc\r
-(MEM_RESERVE, PAGE_NOACCESS) large enough to cover the whole image\r
-(SizeOfImage).  If that is larger than 2 MB, Windows CE automatically\r
-uses the large memory area for the allocation.  Then HiMemCE loads the\r
-sections into the designated place.  This immediately commits all\r
-pages[1].\r
-\r
-The image is then relocated (this is why /FIXED:NO is required).\r
-Although an attempt is made to honor the preferred base address, once\r
-all pages are copied, there is no big advantage to avoiding\r
-relocating, so setting a preferred base address (without a way to also\r
-use MapViewOfFile) is currently not recommended.\r
-\r
-The next step is to resolve imports.  For this, the import section is\r
-processed, and for each DLL listed there, we use LoadLibrary to pass\r
-off the load request to the system loader.  We don't do any DLL\r
-loading ourselves[1].  For every DLL loaded this way, we resolve\r
-references by GetProcAddress, which supports lookup by name as well as\r
-by ordinal.\r
-\r
-Finally, pass execution to the loaded program.  Because the entry\r
-point is a normal C function, we can reuse the current thread and all\r
-its state.  The first argument is the module handle of the started\r
-image.  As we constructed this ourselve, there is no valid module\r
-handle for it, so we reuse the module handle of the loader as well.[3]\r
-Because this affects argv[0], we give the loader the same name as the\r
-executable we want to load (and rename the loaded executable to\r
-foo-real.exe).\r
-\r
-\r
-Footnotes\r
-\r
-[1] This is a pessimization, but because only MapViewOfFile and\r
-not MapVieOfFileEx is available, mapping in the read only sections of\r
-the file directly is difficult, and when relocating the image, many\r
-pages end up being dirty anyway.  See Optimization options.\r
-\r
-[2] This avoids the complexity of sharing DLLs across applications as\r
-well as walking the dependency chain.  A more complex loader, that can\r
-also load DLLs and thus effectively extend the slot 61 and 60 by\r
-further slots is feasible, but quite a bit of work.  The only benefit\r
-over static linking this has is code sharing, but if we are only\r
-talking about a couple of MB, then code duplication across a small\r
-number of programs is not a big problem.  And the number of processes\r
-in Windows CE is necessarily small!\r
-\r
-[3] Note that this could confuse some programs that do deep\r
-introspection and want to manually load custom sections or do other\r
-magic.\r
-\r
-\r
-TODO\r
-----\r
-\r
-* Switch off verbose output for non-himemce.exe named copies of\r
-the loader (but allow a switch --himemce-log to switch it back on).\r
-\r
-* Show load errors in a diagnostic window for the user.\r
-\r
-* Handle DISCARDABLE flag?\r
-\r
-\r
-Optimization options\r
---------------------\r
-\r
-* Physical memory pressure can be relieved by trying to use\r
-  MapViewOfFile opportunistically (create relocated image, save to\r
-  temporary file, map it).\r
-\r
-* Handle DISCARDABLE sections (if any).\r
-\r
-\r
-How it works (DLL version)\r
---------------------------\r
-\r
-The preloader (himemce-pre) should be run when the device starts up,\r
-and must be run before any program is loaded high with himemce.  It\r
-preloads the DLLs that should be loaded high.\r
-\r
-Note that these DLLs are unknown to the system and can only be used by\r
-himemce.  This means that any program resp. DLL that depends on a high\r
-loaded DLL must be loaded by himemce resp. himemce-pre as well.\r
-Further note that himemce can not generate stub code for ARM, so ARM\r
-DLLs such as gpgme, gpg-error etc can not be preloaded and should be\r
-exempted.\r
-\r
-The himemce-pre program looks for all .dll files in its directory and\r
-preloads them, unless they are in the blacklist (FIXME: implement and\r
-document blacklist mechanism).\r
-\r
-The preloader performs the following steps:\r
-\r
-1. For all preloaded DLLs, map them to high memory without resolving\r
-their references.\r
-\r
-2. For all preloaded DLLs, identify sections that are writable and\r
-thus need to be allocated per process.  For these DLLs, reserve some\r
-memory in a continuous range at the bottom of the process address\r
-space (_HIMEMCE_MAP_LOW_BASE == 2 MB).  Also rewrite all base\r
-relocations that point into these sections to point to the low memory\r
-instead.\r
-\r
-3. For all preloaded DLLs, import their dependencies.  For DLLs\r
-managed by himemce-pre, this will resolve to the entry points in the\r
-high loaded DLLs (adjusting entry points into writable section to\r
-their low memory variant).  For system managed DLLs, use the normal\r
-LoadLibrary/GetProcAddressA mechanism.\r
-\r
-4. Map the data structures describing all this to a shared memory\r
-region named HIMEMCE_MAP_NAME == L"himemcemap".  This can be accessed\r
-by himemce.\r
-\r
-5. Sleep forever.  It is important that this process does not exit,\r
-because if this was the last user of HIMEMCE_MAP_NAME, the preloaded\r
-libraries will be deallocated.\r
-\r
-These steps must be executed for programs that run with preloaded\r
-DLLs (done by himemce):\r
-\r
-1. At startup, reserve the low memory sections.\r
-\r
-2. For each preloaded DLL, copy its writable sections to the process\r
-memory reserved in step 1.\r
-\r
-3. For each system DLL that is used by preloaded DLLs, call\r
-LoadLibrary to copy their writable sections into the process memory.\r
-\r
-4. For each preloaded DLL, call DllMain (their entry point).\r
-\r
-[5. TODO: Load a himemce.dll library that calls these DllMain's for\r
-each Thread in its DllMain.]\r
-\r
-\r
- Copyright 2010 g10 Code GmbH\r
-\r
- This file is free software; as a special exception the author gives\r
- unlimited permission to copy and/or distribute it, with or without\r
- modifications, as long as this notice is preserved.\r
-\r
- This file is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY, to the extent permitted by law; without even the\r
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r
+HiMemCE
+=======
+
+HiMemCE is a high memory loader for Windows CE.  It softens the 32 MB
+process limit by allowing the EXE to load in the large file area
+reserved for file mappings.  This way, the EXE can be as large as free
+unfragmented virtual memory in that region, or free physical memory
+(whatever is smaller).  By linking libraries statically to the
+program, problems with too large or too many DLLs can be avoided.
+
+The usage of the loader is very simple.
+
+1. First, the program to be loaded has to be linked with the option
+/FIXED:NO (in MSVS, this setting can be found under Properties,
+Configuration Properties, Linker, Advanced, Fixed Base Address, choose
+"Generate a relocation section").  Here is a CMake example:
+
+SET_TARGET_PROPERTIES(foo PROPERTIES LINK_FLAGS " /FIXED:NO")
+
+2. Install the program "foo" under foo-real.exe, and copy the loader's
+himemce.exe side-by-side to it as foo.exe.  Then the loader (as
+foo.exe) transparently proxies all start ups of the foo program.  It
+will automatically look for foo-real.exe and load that into high
+memory, continueing execution there.
+
+Contained in this package is a himemce-real.exe, that serves as an
+example/test program.  In the special case of "himemce.exe", verbose
+output is on by default.
+
+How it works
+------------
+
+HiMemCE allocates a virtual memory region with VirtulAlloc
+(MEM_RESERVE, PAGE_NOACCESS) large enough to cover the whole image
+(SizeOfImage).  If that is larger than 2 MB, Windows CE automatically
+uses the large memory area for the allocation.  Then HiMemCE loads the
+sections into the designated place.  This immediately commits all
+pages[1].
+
+The image is then relocated (this is why /FIXED:NO is required).
+Although an attempt is made to honor the preferred base address, once
+all pages are copied, there is no big advantage to avoiding
+relocating, so setting a preferred base address (without a way to also
+use MapViewOfFile) is currently not recommended.
+
+The next step is to resolve imports.  For this, the import section is
+processed, and for each DLL listed there, we use LoadLibrary to pass
+off the load request to the system loader.  We don't do any DLL
+loading ourselves[1].  For every DLL loaded this way, we resolve
+references by GetProcAddress, which supports lookup by name as well as
+by ordinal.
+
+Finally, pass execution to the loaded program.  Because the entry
+point is a normal C function, we can reuse the current thread and all
+its state.  The first argument is the module handle of the started
+image.  As we constructed this ourselve, there is no valid module
+handle for it, so we reuse the module handle of the loader as well.[3]
+Because this affects argv[0], we give the loader the same name as the
+executable we want to load (and rename the loaded executable to
+foo-real.exe).
+
+
+Footnotes
+
+[1] This is a pessimization, but because only MapViewOfFile and
+not MapVieOfFileEx is available, mapping in the read only sections of
+the file directly is difficult, and when relocating the image, many
+pages end up being dirty anyway.  See Optimization options.
+
+[2] This avoids the complexity of sharing DLLs across applications as
+well as walking the dependency chain.  A more complex loader, that can
+also load DLLs and thus effectively extend the slot 61 and 60 by
+further slots is feasible, but quite a bit of work.  The only benefit
+over static linking this has is code sharing, but if we are only
+talking about a couple of MB, then code duplication across a small
+number of programs is not a big problem.  And the number of processes
+in Windows CE is necessarily small!
+
+[3] Note that this could confuse some programs that do deep
+introspection and want to manually load custom sections or do other
+magic.
+
+
+TODO
+----
+
+* Switch off verbose output for non-himemce.exe named copies of
+the loader (but allow a switch --himemce-log to switch it back on).
+
+* Show load errors in a diagnostic window for the user.
+
+* Handle DISCARDABLE flag?
+
+
+Optimization options
+--------------------
+
+* Physical memory pressure can be relieved by trying to use
+  MapViewOfFile opportunistically (create relocated image, save to
+  temporary file, map it).
+
+* Handle DISCARDABLE sections (if any).
+
+
+How it works (DLL version)
+--------------------------
+
+The preloader (himemce-pre) should be run when the device starts up,
+and must be run before any program is loaded high with himemce.  It
+preloads the DLLs that should be loaded high.
+
+Note that these DLLs are unknown to the system and can only be used by
+himemce.  This means that any program resp. DLL that depends on a high
+loaded DLL must be loaded by himemce resp. himemce-pre as well.
+Further note that himemce can not generate stub code for ARM, so ARM
+DLLs such as gpgme, gpg-error etc can not be preloaded and should be
+exempted.
+
+The himemce-pre program looks for all .dll files in its directory and
+preloads them, unless they are in the blacklist (FIXME: implement and
+document blacklist mechanism).
+
+The preloader performs the following steps:
+
+1. For all preloaded DLLs, map them to high memory without resolving
+their references.
+
+2. For all preloaded DLLs, identify sections that are writable and
+thus need to be allocated per process.  For these DLLs, reserve some
+memory in a continuous range at the bottom of the process address
+space (_HIMEMCE_MAP_LOW_BASE == 2 MB).  Also rewrite all base
+relocations that point into these sections to point to the low memory
+instead.
+
+3. For all preloaded DLLs, import their dependencies.  For DLLs
+managed by himemce-pre, this will resolve to the entry points in the
+high loaded DLLs (adjusting entry points into writable section to
+their low memory variant).  For system managed DLLs, use the normal
+LoadLibrary/GetProcAddressA mechanism.
+
+4. Map the data structures describing all this to a shared memory
+region named HIMEMCE_MAP_NAME == L"himemcemap".  This can be accessed
+by himemce.
+
+5. Sleep forever.  It is important that this process does not exit,
+because if this was the last user of HIMEMCE_MAP_NAME, the preloaded
+libraries will be deallocated.
+
+These steps must be executed for programs that run with preloaded
+DLLs (done by himemce):
+
+1. At startup, reserve the low memory sections.
+
+2. For each preloaded DLL, copy its writable sections to the process
+memory reserved in step 1.
+
+3. For each system DLL that is used by preloaded DLLs, call
+LoadLibrary to copy their writable sections into the process memory.
+
+4. For each preloaded DLL, call DllMain (their entry point).
+
+[5. TODO: Load a himemce.dll library that calls these DllMain's for
+each Thread in its DllMain.]
+
+
+ Copyright 2010 g10 Code GmbH
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.