2011-05-11 Ryan Johnson * child_info.h (fork_api_fatal): new macro for reporting to the parent of a forked child that the fork cannot continue. * fork.cc (frok::child): check for clobbered DLL_LOAD early while we can still retry. Exit cleanly and report to parent if fork failed for well-known reasons (clobbered address space). Also, set in_forkee=false at end of fork even if no DLL_LOAD are present. (fork): sort the dll list topologically before forking. When the child loads each dll, all dependencies are already loaded and will no longer risk being pulled in unexpectedly. * heap.cc (heap_init): use fork_api_fatal for clean exit/retry of failed fork. * pinfo.h: define new EXITCODE_FORK_FAILED to aid clean exit/retry of failed forks. * sigproc.cc (child_info::proc_retry): see above. (child_info_fork::handle_failure): ditto. * dll_init.cc (dll_list::find_by_modname): new function to search the dll list for a module name only (no path). (dll_list::alloc): added code which aborts a fork attempt if DLL_LINK dlls landed at the wrong base address in the child. Also, initialize newly-added members of the dll class. (dll_list::topsort, dll_list::topsort_visit): new functions to sort the dll list topologically by dependencies (dll_list::append): new function to factor out the append operation (used by dll_list::topsort) (dll_list::populate_deps): new function to identify dll dependencies (dll_list::block_bad_address_space): new function to reserve all free space in the low 4MB. Reduces somewhat the probability of a dynamic dll clashing with windows heaps or thread stacks. (reserve_upto, release_upto): removed (buggy, no longer needed) (reserve_at): no longer reserves space needed by the target dll if the latter overlaps the free region to be blocked. (dll_list::reserve_space): new function to reserve all space needed by DLL_LOAD dlls early in the fork process. (dll_list::load_after_fork): rewritten. New version uses recursion to track reservations it makes while trying to make dlls land where they belong. No longer set in_forkee=false (now done in fork.cc) * dll_init.h (dll_list, dll): added new class members to support topsort and other improvements to forking. No longer run dtors if in_forkee is true. (pefile): New class allowing simple introspection of dll images. * dcrt0.cc (dll_crt0_1): call dll_list::block_bad_address_space