Commit in reactos on ELF_support
include/elf/common.h+115-221.1.2.1 -> 1.1.2.2
           /elf-i386.h+10-61.1.2.1 -> 1.1.2.2
           /elf32.h+5-51.1.2.1 -> 1.1.2.2
           /elf64.h+6-61.1.2.1 -> 1.1.2.2
           /machine.h+21.1.2.1 -> 1.1.2.2
include/pe.h+71.19.32.2 -> 1.19.32.3
include/reactos/exeformat.h+19-21.1.2.4 -> 1.1.2.5
lib/ntdll/ldr/utils.c+1-371.101.2.1 -> 1.101.2.2
ntoskrnl/Makefile+21.156.2.3 -> 1.156.2.4
ntoskrnl/include/internal/mm.h+7-141.93.2.2 -> 1.93.2.3
ntoskrnl/mm/elf32.c+145added 1.1.2.1
           /elf64.c+2added 1.1.2.1
           /elf.c+666-3431.1.2.1 -> 1.1.2.2
           /pe.c+59-911.1.2.4 -> 1.1.2.5
           /section.c+328-4071.166.2.4 -> 1.166.2.5
ntoskrnl/mm/i386/page.c+34-341.77.2.4 -> 1.77.2.5
+1408-967
2 added + 14 modified, total 16 files
 - include/elf/common.h: use EM_XXX constants straight from the ABI (the most complete list)
 - include/elf/elf-i386.h, include/elf/machine.h: allow architecture-specific headers not matching the build target to be included
 - include/elf/elf32.h, include/elf/elf64.h: use long integer types because nearly all the code in ReactOS does
 - include/pe.h: added some missing constants
 - include/reactos/exefmt.h: added some constants required for full ELF support
 - lib/ntdll/ldr/utils.c: deleted experimental DbgPrint calls I committed by mistake
 - ntoskrnl/Makefile, ntoskrnl/mm/elf.c, ntoskrnl/mm/elf32.c, ntoskrnl/mm/elf64.c: ELF support added to the memory manager. It supports both ELF32 and ELF64, on all architectures, and can map executables with the "wrong" architecture and endianness as required for SEC_IMAGE sections. Scrapped the limited FreeBSD implementation completely. Limits of the loader: doesn't support non-contiguous images (like several non-PIC EXEs), doesn't support images with a virtual size larger than 4GB, doesn't support images with loadable parts whose file offset + size points to beyond ~8EB (Exabytes) into the file - all internal hard limits of the kernel I don't feel like fixing right now - and doesn't fully support Winelib executables yet
 - ntoskrnl/include/internal/mm.h: use LONGLONG for MM_SECTION_SEGMENT.FileOffset, reintroduced MM_SECTION_SEGMENT.WriteCopy, re-limit segments to 4GB each (will raise the limit to MAXULONG_PTR shortly)
 - ntoskrnl/mm/386/page.c: partial merge with HEAD
 - ntoskrnl/mm/pe.c: cleanup of data types, internal helper functions and debug messages; corrected some small bugs; added ASSERTs; set the correct characteristics for the headers segment; adapted to the reintroduction of MM_SECTION_SEGMENT.WriteCopy; disabled debug messages
 - ntoskrnl/mm/section.c: major cleanup, bug-hunt came to an end, finalized the preliminary support for multiple executable formats, temporarily gave up about a lot of ugliness

reactos/include/elf
common.h 1.1.2.1 -> 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- common.h	8 Dec 2004 20:01:39 -0000	1.1.2.1
+++ common.h	30 Dec 2004 01:59:58 -0000	1.1.2.2
@@ -117,28 +117,121 @@
 #define ET_CORE		4	/* Core file. */
 
 /* Values for e_machine. */
-#define EM_NONE		0	/* Unknown machine. */
-#define EM_M32		1	/* AT&T WE32100. */
-#define EM_SPARC	2	/* Sun SPARC. */
-#define EM_386		3	/* Intel i386. */
-#define EM_68K		4	/* Motorola 68000. */
-#define EM_88K		5	/* Motorola 88000. */
-#define EM_486		6	/* Intel i486. */
-#define EM_860		7	/* Intel i860. */
-#define EM_MIPS		8	/* MIPS R3000 Big-Endian only */
-
-/* Extensions.  This list is not complete. */
-#define EM_S370		9	/* IBM System/370 */
-#define EM_MIPS_RS4_BE	10	/* MIPS R4000 Big-Endian */ /* Depreciated */
-#define EM_PARISC	15	/* HPPA */
-#define EM_SPARC32PLUS	18	/* SPARC v8plus */
-#define EM_PPC		20	/* PowerPC 32-bit */
-#define EM_PPC64	21	/* PowerPC 64-bit */
-#define EM_ARM		40	/* ARM */
-#define EM_SPARCV9	43	/* SPARC v9 64-bit */
-#define EM_IA_64	50	/* Intel IA-64 Processor */
-#define EM_X86_64	62	/* Advanced Micro Devices x86-64 */
-#define EM_ALPHA	0x9026	/* Alpha (written in the absence of an ABI */
+/*
+ * Source:
+ *  System V Application Binary Interface (DRAFT) 2003-12-17, Chapter 4, Section
+ *  "ELF Header"
+ */
+#define EM_NONE 	0	/* No machine */
+#define EM_M32  	1	/* AT&T WE 32100 */
+#define EM_SPARC	2	/* SPARC */
+#define EM_386  	3	/* Intel 80386 */
+#define EM_68K  	4	/* Motorola 68000 */
+#define EM_88K  	5	/* Motorola 88000 */
+/*      reserved	6	   Reserved for future use (was EM_486) */
+#define EM_860  	7	/* Intel 80860 */
+#define EM_MIPS 	8	/* MIPS I Architecture */
+#define EM_S370 	9	/* IBM System/370 Processor */
+#define EM_MIPS_RS3_LE	10	/* MIPS RS3000 Little-endian */
+/*      reserved	11-14	   Reserved for future use */
+#define EM_PARISC	15	/* Hewlett-Packard PA-RISC */
+/*      reserved	16	   Reserved for future use */
+#define EM_VPP500	17	/* Fujitsu VPP500 */
+#define EM_SPARC32PLUS	18	/* Enhanced instruction set SPARC */
+#define EM_960  	19	/* Intel 80960 */
+#define EM_PPC  	20	/* PowerPC */
+#define EM_PPC64	21	/* 64-bit PowerPC */
+#define EM_S390 	22	/* IBM System/390 Processor */
+/*      reserved	23-35	   Reserved for future use */
+#define EM_V800 	36	/* NEC V800 */
+#define EM_FR20 	37	/* Fujitsu FR20 */
+#define EM_RH32 	38	/* TRW RH-32 */
+#define EM_RCE  	39	/* Motorola RCE */
+#define EM_ARM  	40	/* Advanced RISC Machines ARM */
+#define EM_ALPHA	41	/* Digital Alpha */
+#define EM_SH   	42	/* Hitachi SH */
+#define EM_SPARCV9	43	/* SPARC Version 9 */
+#define EM_TRICORE	44	/* Siemens TriCore embedded processor */
+#define EM_ARC  	45	/* Argonaut RISC Core, Argonaut Technologies
+				   Inc. */
+#define EM_H8_300	46	/* Hitachi H8/300 */
+#define EM_H8_300H	47	/* Hitachi H8/300H */
+#define EM_H8S  	48	/* Hitachi H8S */
+#define EM_H8_500	49	/* Hitachi H8/500 */
+#define EM_IA_64	50	/* Intel IA-64 processor architecture */
+#define EM_MIPS_X	51	/* Stanford MIPS-X */
+#define EM_COLDFIRE	52	/* Motorola ColdFire */
+#define EM_68HC12	53	/* Motorola M68HC12 */
+#define EM_MMA  	54	/* Fujitsu MMA Multimedia Accelerator */
+#define EM_PCP  	55	/* Siemens PCP */
+#define EM_NCPU 	56	/* Sony nCPU embedded RISC processor */
+#define EM_NDR1 	57	/* Denso NDR1 microprocessor */
+#define EM_STARCORE	58	/* Motorola Star*Core processor */
+#define EM_ME16 	59	/* Toyota ME16 processor */
+#define EM_ST100	60	/* STMicroelectronics ST100 processor */
+#define EM_TINYJ	61	/* Advanced Logic Corp. TinyJ embedded processor
+				   family */
+#define EM_X86_64	62	/* AMD x86-64 architecture */
+#define EM_PDSP 	63	/* Sony DSP Processor */
+#define EM_PDP10	64	/* Digital Equipment Corp. PDP-10 */
+#define EM_PDP11	65	/* Digital Equipment Corp. PDP-11 */
+#define EM_FX66 	66	/* Siemens FX66 microcontroller */
+#define EM_ST9PLUS	67	/* STMicroelectronics ST9+ 8/16 bit
+				   microcontroller */
+#define EM_ST7  	68	/* STMicroelectronics ST7 8-bit
+				   microcontroller */
+#define EM_68HC16	69	/* Motorola MC68HC16 Microcontroller */
+#define EM_68HC11	70	/* Motorola MC68HC11 Microcontroller */
+#define EM_68HC08	71	/* Motorola MC68HC08 Microcontroller */
+#define EM_68HC05	72	/* Motorola MC68HC05 Microcontroller */
+#define EM_SVX  	73	/* Silicon Graphics SVx */
+#define EM_ST19 	74	/* STMicroelectronics ST19 8-bit
+				   microcontroller */
+#define EM_VAX  	75	/* Digital VAX */
+#define EM_CRIS 	76	/* Axis Communications 32-bit embedded
+				   processor */
+#define EM_JAVELIN	77	/* Infineon Technologies 32-bit embedded
+				   processor */
+#define EM_FIREPATH	78	/* Element 14 64-bit DSP Processor */
+#define EM_ZSP  	79	/* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX 	80	/* Donald Knuth's educational 64-bit
+				   processor */
+#define EM_HUANY	81	/* Harvard University machine-independent object
+				   files */
+#define EM_PRISM	82	/* SiTera Prism */
+#define EM_AVR  	83	/* Atmel AVR 8-bit microcontroller */
+#define EM_FR30 	84	/* Fujitsu FR30 */
+#define EM_D10V 	85	/* Mitsubishi D10V */
+#define EM_D30V 	86	/* Mitsubishi D30V */
+#define EM_V850 	87	/* NEC v850 */
+#define EM_M32R 	88	/* Mitsubishi M32R */
+#define EM_MN10300	89	/* Matsushita MN10300 */
+#define EM_MN10200	90	/* Matsushita MN10200 */
+#define EM_PJ   	91	/* picoJava */
+#define EM_OPENRISC	92	/* OpenRISC 32-bit embedded processor */
+#define EM_ARC_A5	93	/* ARC Cores Tangent-A5 */
+#define EM_XTENSA	94	/* Tensilica Xtensa Architecture */
+#define EM_VIDEOCORE	95	/* Alphamosaic VideoCore processor */
+#define EM_TMM_GPP	96	/* Thompson Multimedia General Purpose
+				   Processor */
+#define EM_NS32K	97	/* National Semiconductor 32000 series */
+#define EM_TPC  	98	/* Tenor Network TPC processor */
+#define EM_SNP1K	99	/* Trebia SNP 1000 processor */
+#define EM_ST200	100	/* STMicroelectronics (www.st.com) ST200
+				   microcontroller */
+#define EM_IP2K 	101	/* Ubicom IP2xxx microcontroller family */
+#define EM_MAX  	102	/* MAX Processor */
+#define EM_CR   	103	/* National Semiconductor CompactRISC
+				   microprocessor */
+#define EM_F2MC16	104	/* Fujitsu F2MC16 */
+#define EM_MSP430	105	/* Texas Instruments embedded microcontroller
+				   msp430 */
+#define EM_BLACKFIN	106	/* Analog Devices Blackfin (DSP) processor */
+#define EM_SE_C33	107	/* S1C33 Family of Seiko Epson processors */
+#define EM_SEP  	108	/* Sharp embedded microprocessor */
+#define EM_ARCA 	109	/* Arca RISC Microprocessor */
+#define EM_UNICORE	110	/* Microprocessor series from PKU-Unity Ltd. and
+				   MPRC of Peking University */
 
 /* Special section indexes. */
 #define SHN_UNDEF	     0		/* Undefined, missing, irrelevant. */

reactos/include/elf
elf-i386.h 1.1.2.1 -> 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- elf-i386.h	8 Dec 2004 20:01:39 -0000	1.1.2.1
+++ elf-i386.h	30 Dec 2004 01:59:58 -0000	1.1.2.2
@@ -33,6 +33,8 @@
  * ELF definitions for the i386 architecture.
  */
 
+#ifdef _REACTOS_ELF_MACHINE_IS_TARGET
+
 #ifndef __ELF_WORD_SIZE
 #define	__ELF_WORD_SIZE	32	/* Used by <elf/generic.h> */
 #endif
@@ -102,6 +104,14 @@
 
 #define	AT_COUNT	15	/* Count of defined aux entry types. */
 
+/* Define "machine" characteristics */
+#define	ELF_TARG_CLASS	ELFCLASS32
+#define	ELF_TARG_DATA	ELFDATA2LSB
+#define	ELF_TARG_MACH	EM_386
+#define	ELF_TARG_VER	1
+
+#endif /* _REACTOS_ELF_MACHINE_IS_TARGET */
+
 /*
  * Relocation types.
  */
@@ -140,10 +150,4 @@
 
 #define	R_386_COUNT	38	/* Count of defined relocation types. */
 
-/* Define "machine" characteristics */
-#define	ELF_TARG_CLASS	ELFCLASS32
-#define	ELF_TARG_DATA	ELFDATA2LSB
-#define	ELF_TARG_MACH	EM_386
-#define	ELF_TARG_VER	1
-
 #endif /* !_MACHINE_ELF_H_ */

reactos/include/elf
elf32.h 1.1.2.1 -> 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- elf32.h	8 Dec 2004 20:01:39 -0000	1.1.2.1
+++ elf32.h	30 Dec 2004 01:59:58 -0000	1.1.2.2
@@ -33,12 +33,12 @@
  * ELF definitions common to all 32-bit architectures.
  */
 
-typedef UINT32	Elf32_Addr;
+typedef ULONG32	Elf32_Addr;
 typedef USHORT	Elf32_Half;
-typedef UINT32	Elf32_Off;
-typedef INT32		Elf32_Sword;
-typedef UINT32	Elf32_Word;
-typedef UINT32	Elf32_Size;
+typedef ULONG32	Elf32_Off;
+typedef LONG32	Elf32_Sword;
+typedef ULONG32	Elf32_Word;
+typedef ULONG32	Elf32_Size;
 typedef Elf32_Off	Elf32_Hashelt;
 
 /*

reactos/include/elf
elf64.h 1.1.2.1 -> 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- elf64.h	8 Dec 2004 20:01:39 -0000	1.1.2.1
+++ elf64.h	30 Dec 2004 01:59:58 -0000	1.1.2.2
@@ -33,12 +33,12 @@
  * ELF definitions common to all 64-bit architectures.
  */
 
-typedef UINT64	Elf64_Addr;
-typedef UINT32	Elf64_Half;
-typedef UINT64	Elf64_Off;
-typedef INT64		Elf64_Sword;
-typedef UINT64	Elf64_Word;
-typedef UINT64	Elf64_Size;
+typedef ULONG64	Elf64_Addr;
+typedef ULONG32	Elf64_Half;
+typedef ULONG64	Elf64_Off;
+typedef LONG64	Elf64_Sword;
+typedef ULONG64	Elf64_Word;
+typedef ULONG64	Elf64_Size;
 typedef USHORT	Elf64_Quarter;
 
 /*

reactos/include/elf
machine.h 1.1.2.1 -> 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- machine.h	8 Dec 2004 20:01:39 -0000	1.1.2.1
+++ machine.h	30 Dec 2004 01:59:58 -0000	1.1.2.2
@@ -2,7 +2,9 @@
 #define _REACTOS_ELF_MACHINE_H_ 1
 
 #ifdef _M_IX86
+#define _REACTOS_ELF_MACHINE_IS_TARGET
 #include <elf/elf-i386.h>
+#undef _REACTOS_ELF_MACHINE_IS_TARGET
 #else
 #error Unsupported target architecture
 #endif

reactos/include
pe.h 1.19.32.2 -> 1.19.32.3
diff -u -r1.19.32.2 -r1.19.32.3
--- pe.h	13 Dec 2004 05:55:31 -0000	1.19.32.2
+++ pe.h	30 Dec 2004 01:59:58 -0000	1.19.32.3
@@ -40,6 +40,7 @@
 #define IMAGE_FILE_EXECUTABLE_IMAGE          0x0002  // File is executable  (i.e. no unresolved externel references).
 #define IMAGE_FILE_LINE_NUMS_STRIPPED        0x0004  // Line nunbers stripped from file.
 #define IMAGE_FILE_LOCAL_SYMS_STRIPPED       0x0008  // Local symbols stripped from file.
+#define IMAGE_FILE_LARGE_ADDRESS_AWARE       0x0020  // Application supports addresses >2GB
 #define IMAGE_FILE_BYTES_REVERSED_LO         0x0080  // Bytes of machine word are reversed.
 #define IMAGE_FILE_32BIT_MACHINE             0x0100  // 32 bit word machine.
 #define IMAGE_FILE_DEBUG_STRIPPED            0x0200  // Debugging info stripped from file in .DBG file
@@ -57,6 +58,12 @@
 #define IMAGE_FILE_MACHINE_R10000            0x168   // MIPS little-endian
 #define IMAGE_FILE_MACHINE_ALPHA             0x184   // Alpha_AXP
 #define IMAGE_FILE_MACHINE_POWERPC           0x1F0   // IBM PowerPC Little-Endian
+#define IMAGE_FILE_MACHINE_ARM               0x01c0  // ARM little-endian
+#define IMAGE_FILE_MACHINE_IA64              0x0200  // Intel IA64
+#define IMAGE_FILE_MACHINE_AXP64             IMAGE_FILE_MACHINE_ALPHA64
+#define IMAGE_FILE_MACHINE_ALPHA64           0x0284  // Alpha AXP, full 64-bit support
+#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD x86-64
+#define IMAGE_FILE_MACHINE_M32R              0x9041  // M32R little-endian
 
 #pragma pack(push,4)
 typedef struct _IMAGE_FILE_HEADER {

reactos/include/reactos
exeformat.h 1.1.2.4 -> 1.1.2.5
diff -u -r1.1.2.4 -r1.1.2.5
--- exeformat.h	18 Dec 2004 02:58:55 -0000	1.1.2.4
+++ exeformat.h	30 Dec 2004 01:59:58 -0000	1.1.2.5
@@ -4,6 +4,7 @@
 /*
  * LOADER API
  */
+/* OUT flags returned by a loader */
 #define EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED       (1 << 0)
 #define EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP   (1 << 1)
 #define EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED (1 << 2)
@@ -15,9 +16,25 @@
   EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED \
  )
 
+/*
+ Minumum size of the buffer passed to each loader for identification of the
+ executable
+*/
+#define EXEFMT_LOAD_HEADER_SIZE (0x2000)
+
+/* Special values for the base address of images */
+/*
+ Base address can't be represented in an ULONG_PTR: any effective load address
+ will require relocation
+*/
+#define EXEFMT_LOAD_BASE_NONE ((ULONG_PTR)-1)
+
+/* Base address never matters, relocation never required */
+#define EXEFMT_LOAD_BASE_ANY  ((ULONG_PTR)-2)
+
 typedef NTSTATUS (NTAPI * PEXEFMT_CB_READ_FILE)
 (
- IN PFILE_OBJECT FileObject,
+ IN PVOID File,
  IN PLARGE_INTEGER Offset,
  IN ULONG Length,
  OUT PVOID * Data,
@@ -34,7 +51,7 @@
 (
  IN CONST VOID * FileHeader,
  IN SIZE_T FileHeaderSize,
- IN PFILE_OBJECT File,
+ IN PVOID File,
  OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
  OUT PULONG Flags,
  IN PEXEFMT_CB_READ_FILE ReadFileCb,

reactos/lib/ntdll/ldr
utils.c 1.101.2.1 -> 1.101.2.2
diff -u -r1.101.2.1 -r1.101.2.2
--- utils.c	8 Dec 2004 21:57:14 -0000	1.101.2.1
+++ utils.c	30 Dec 2004 01:59:58 -0000	1.101.2.2
@@ -1,4 +1,4 @@
-/* $Id: utils.c,v 1.101.2.1 2004/12/08 21:57:14 hyperion Exp $
+/* $Id: utils.c,v 1.101.2.2 2004/12/30 01:59:58 hyperion Exp $
  * 
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -720,9 +720,6 @@
   NTSTATUS              Status;
   PLDR_MODULE           Module;
 
-  /* HACKHACK */
-  DbgPrint("LdrLoadDll(%S, %x, %wZ, %p)\n", SearchPath, LoadFlags, Name, BaseAddress);
-
   TRACE_LDR("LdrLoadDll, loading %wZ%s%S\n",
             Name,
             SearchPath ? " from " : "",
@@ -775,9 +772,6 @@
   PLIST_ENTRY Entry;
   PLDR_MODULE ModulePtr;
 
-  /* HACKHACK */
-  DbgPrint("LdrFindEntryForAddress(%p, %p)\n", Address, Module);
-
   DPRINT("LdrFindEntryForAddress(Address %p)\n", Address);
 
   if (NtCurrentPeb()->Ldr == NULL)
@@ -843,9 +837,6 @@
   UNICODE_STRING AdjustedName;
   unsigned i;
 
-  /* HACKHACK */
-  DbgPrint("LdrFindEntryForName(%wZ, %p, %d)\n", Name, Module, Ref);
-
   DPRINT("LdrFindEntryForName(Name %wZ)\n", Name);
 
   if (NtCurrentPeb()->Ldr == NULL)
@@ -2220,10 +2211,6 @@
    PLDR_MODULE Module;
    NTSTATUS Status;
 
-   /* HACKHACK */
-  DbgPrint("LdrUnloadDll(%p)\n", BaseAddress);
-
-
    if (BaseAddress == NULL)
      return STATUS_SUCCESS;
 
@@ -2247,9 +2234,6 @@
     PLDR_MODULE Module;
     NTSTATUS Status;
 
-   /* HACKHACK */
-   DbgPrint("LdrDisableThreadCalloutsForDll(%p)\n", BaseAddress);
-
     DPRINT("LdrDisableThreadCalloutsForDll (BaseAddress %x)\n", BaseAddress);
 
     Status = STATUS_DLL_NOT_FOUND;
@@ -2289,9 +2273,6 @@
     PLDR_MODULE Module;
     NTSTATUS Status;
 
-  /* HACKHACK */
-  DbgPrint("LdrGetDllHandle(%S, %x, %wZ, %p)\n", Path, Unknown2, DllName, BaseAddress);
-
     TRACE_LDR("LdrGetDllHandle, searching for %wZ from %S\n", DllName, Path ? Path : L"");
 
     /* NULL is the current executable */
@@ -2324,9 +2305,6 @@
                         IN ULONG Ordinal,
                         OUT PVOID *ProcedureAddress)
 {
-  /* HACKHACK */
-  DbgPrint("LdrGetProcedureAddress(%p, %Z, %d, %p)\n", BaseAddress, Name, Ordinal, ProcedureAddress);
-
    if (Name && Name->Length)
      {
        TRACE_LDR("LdrGetProcedureAddress by NAME - %Z\n", Name);
@@ -2527,8 +2505,6 @@
 NTSTATUS STDCALL
 LdrShutdownProcess (VOID)
 {
-  /* HACKHACK */
-  DbgPrint("LdrShutdownProcess()\n");
   LdrpDetachProcess(TRUE);
   return STATUS_SUCCESS;
 }
@@ -2545,9 +2521,6 @@
   PLDR_MODULE Module;
   NTSTATUS Status;
 
-  /* HACKHACK */
-  DbgPrint("LdrpAttachThread()\n");
-
   DPRINT("LdrpAttachThread() called for %wZ\n",
          &ExeModule->BaseDllName);
 
@@ -2597,9 +2570,6 @@
    PLIST_ENTRY Entry;
    PLDR_MODULE Module;
 
-  /* HACKHACK */
-  DbgPrint("LdrShutdownThread()\n");
-
    DPRINT("LdrShutdownThread() called for %wZ\n",
           &ExeModule->BaseDllName);
 
@@ -2835,9 +2805,6 @@
   BOOLEAN Result;
   NTSTATUS Status;
 
-  /* HACKHACK */
-  DbgPrint("LdrVerifyImageMatchesChecksum(%p, %x, %x, %x)\n", FileHandle, Unknown1, Unknown2, Unknown3);
-
   DPRINT ("LdrVerifyImageMatchesChecksum() called\n");
 
   Status = NtCreateSection (&SectionHandle,
@@ -2937,9 +2904,6 @@
   PWCHAR Ptr;
   NTSTATUS Status;
 
-  /* HACKHACK */
-  DbgPrint("LdrQueryImageFileExecutionOptions(%wZ, %S, %x, %p, %d, %p)\n", SubKey, ValueName, Type, Buffer, BufferSize, ReturnedLength);
-
   wcscpy (NameBuffer,
           L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\");
   Ptr = wcsrchr (SubKey->Buffer, L'\\');

reactos/ntoskrnl
Makefile 1.156.2.3 -> 1.156.2.4
diff -u -r1.156.2.3 -r1.156.2.4
--- Makefile	13 Dec 2004 09:39:07 -0000	1.156.2.3
+++ Makefile	30 Dec 2004 01:59:59 -0000	1.156.2.4
@@ -144,6 +144,8 @@
 	mm/balance.o \
 	mm/cont.o \
 	mm/drvlck.o \
+	mm/elf32.o \
+	mm/elf64.o \
 	mm/freelist.o \
 	mm/iospace.o \
 	mm/kmap.o \

reactos/ntoskrnl/include/internal
mm.h 1.93.2.2 -> 1.93.2.3
diff -u -r1.93.2.2 -r1.93.2.3
--- mm.h	13 Dec 2004 05:55:32 -0000	1.93.2.2
+++ mm.h	30 Dec 2004 01:59:59 -0000	1.93.2.3
@@ -108,16 +108,17 @@
 
 typedef struct _MM_SECTION_SEGMENT
 {
-  ULONG FileOffset;
-  ULONG RawLength;
+  LONGLONG FileOffset;
   ULONG_PTR VirtualAddress;
-  SIZE_T Length;
+  ULONG RawLength;
+  ULONG Length;
   ULONG Protection;
-  LONG ReferenceCount;
-  ULONG Flags;
-  ULONG Characteristics;
   FAST_MUTEX Lock;
+  ULONG ReferenceCount;
   SECTION_PAGE_DIRECTORY PageDirectory;
+  ULONG Flags;
+  ULONG Characteristics;
+  BOOLEAN WriteCopy;
 } MM_SECTION_SEGMENT, *PMM_SECTION_SEGMENT;
 
 typedef struct _MM_IMAGE_SECTION_OBJECT
@@ -386,14 +387,6 @@
 
 NTSTATUS MmUnlockMemoryArea(MEMORY_AREA* MemoryArea);
 
-PMEMORY_AREA MmSplitMemoryArea(struct _EPROCESS* Process,
-			       PMADDRESS_SPACE AddressSpace,
-			       PMEMORY_AREA OriginalMemoryArea,
-			       PVOID BaseAddress,
-			       ULONG Length,
-			       ULONG NewType,
-			       ULONG NewAttributes);
-
 MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace, 
 				      PVOID Address,
 				      ULONG Length);

reactos/ntoskrnl/mm
elf32.c added at 1.1.2.1
diff -N elf32.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ elf32.c	30 Dec 2004 01:59:59 -0000	1.1.2.1
@@ -0,0 +1,145 @@
+#define __ELF_WORD_SIZE 32
+#include "elf.c"
+
+extern NTSTATUS NTAPI Elf64FmtCreateSection
+(
+ IN CONST VOID * FileHeader,
+ IN SIZE_T FileHeaderSize,
+ IN PVOID File,
+ OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
+ OUT PULONG Flags,
+ IN PEXEFMT_CB_READ_FILE ReadFileCb,
+ IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
+);
+
+NTSTATUS NTAPI ElfFmtCreateSection
+(
+ IN CONST VOID * FileHeader,
+ IN SIZE_T FileHeaderSize,
+ IN PVOID File,
+ OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
+ OUT PULONG Flags,
+ IN PEXEFMT_CB_READ_FILE ReadFileCb,
+ IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
+)
+{
+ ULONG nDataType;
+ const Elf32_Ehdr * pehTempHeader;
+
+ ASSERT(FileHeader);
+ ASSERT(FileHeaderSize > 0);
+ ASSERT(Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize));
+ ASSERT(File);
+ ASSERT(ImageSectionObject);
+ ASSERT(Flags);
+ ASSERT(ReadFileCb);
+ ASSERT(AllocateSegmentsCb);
+
+ pehTempHeader = FileHeader;
+ ASSERT(((ULONG_PTR)pehTempHeader % TYPE_ALIGNMENT(Elf32_Ehdr)) == 0);
+ ASSERT(((ULONG_PTR)pehTempHeader % TYPE_ALIGNMENT(Elf64_Ehdr)) == 0);
+
+ ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_ident));
+
+ /* File too small to be identified */
+ if(!RTL_CONTAINS_FIELD(pehTempHeader, FileHeaderSize, e_ident[EI_MAG3]))
+  return STATUS_ROS_EXEFMT_UNKNOWN_FORMAT;
+
+ /* Not an ELF file */
+ if
+ (
+  pehTempHeader->e_ident[EI_MAG0] != ELFMAG0 ||
+  pehTempHeader->e_ident[EI_MAG1] != ELFMAG1 ||
+  pehTempHeader->e_ident[EI_MAG2] != ELFMAG2 ||
+  pehTempHeader->e_ident[EI_MAG3] != ELFMAG3
+ )
+  return STATUS_ROS_EXEFMT_UNKNOWN_FORMAT;
+
+ /* Validate the data type */
+ nDataType = pehTempHeader->e_ident[EI_DATA];
+
+ switch(nDataType)
+ {
+  case ELFDATA2LSB:
+  case ELFDATA2MSB:
+   break;
+
+  default:
+   return STATUS_INVALID_IMAGE_FORMAT;
+ }
+
+ /* Validate the version */
+ ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_version));
+
+ if
+ (
+  pehTempHeader->e_ident[EI_VERSION] != EV_CURRENT ||
+  ElfFmtpReadULong(pehTempHeader->e_version, nDataType) != EV_CURRENT
+ )
+  return STATUS_INVALID_IMAGE_FORMAT;
+
+ /* Validate the file type */
+ ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_type));
+
+ switch(ElfFmtpReadUShort(pehTempHeader->e_type, nDataType))
+ {
+  case ET_DYN: ImageSectionObject->ImageCharacteristics |= IMAGE_FILE_DLL;
+  case ET_EXEC: break;
+  default: return STATUS_INVALID_IMAGE_FORMAT;
+ }
+
+ /* Convert the target machine */
+ ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_machine));
+ ASSERT(ImageSectionObject->Machine == IMAGE_FILE_MACHINE_UNKNOWN);
+
+ switch(ElfFmtpReadUShort(pehTempHeader->e_machine, nDataType))
+ {
+  case EM_386: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_I386; break;
+  case EM_MIPS_RS3_LE: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_R3000; break;
+
+#if 0
+  /* TODO: need to read e_flags for full identification */
+  case EM_SH: break;
+#endif
+
+  case EM_ARM: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_ARM; break;
+  case EM_PPC: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_POWERPC; break;
+  case EM_IA_64: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_IA64; break;
+  case EM_ALPHA: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_AXP64; break;
+  case EM_X86_64: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_AMD64; break;
+  case EM_M32R: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_M32R; break;
+ }
+
+ /* Call the appropriate handler for the class-specific fields */
+ switch(pehTempHeader->e_ident[EI_CLASS])
+ {
+  case ELFCLASS32:
+   return Elf32FmtCreateSection
+   (
+    FileHeader,
+    FileHeaderSize,
+    File,
+    ImageSectionObject,
+    Flags,
+    ReadFileCb,
+    AllocateSegmentsCb
+   );
+
+  case ELFCLASS64:
+   return Elf64FmtCreateSection
+   (
+    FileHeader,
+    FileHeaderSize,
+    File,
+    ImageSectionObject,
+    Flags,
+    ReadFileCb,
+    AllocateSegmentsCb
+   );
+ }
+
+ /* Unknown class */
+ return STATUS_INVALID_IMAGE_FORMAT;
+}
+
+/* EOF */

reactos/ntoskrnl/mm
elf64.c added at 1.1.2.1
diff -N elf64.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ elf64.c	30 Dec 2004 01:59:59 -0000	1.1.2.1
@@ -0,0 +1,2 @@
+#define __ELF_WORD_SIZE 64
+#include "elf.c"

reactos/ntoskrnl/mm
elf.c 1.1.2.1 -> 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- elf.c	3 Dec 2004 14:17:10 -0000	1.1.2.1
+++ elf.c	30 Dec 2004 01:59:59 -0000	1.1.2.2
@@ -1,379 +1,702 @@
-/* $Id: elf.c,v 1.1.2.1 2004/12/03 14:17:10 hyperion Exp $
+/* $Id: elf.c,v 1.1.2.2 2004/12/30 01:59:59 hyperion Exp $
 */
 
-/*
- * REACTOS ELF MAPPER
- *
- * ELF mapper, ported from FreeBSD by KJK::Hyperion as part of the ELF support
- * initiative. Original copyright, licensing and disclaimers follow
- */
+#include <ntoskrnl.h>
 
-/*-
- * Copyright 1996-1998 John D. Polstra.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: src/libexec/rtld-elf/map_object.c,v 1.15 2004/08/03 08:50:58 dfr Exp $
- */
+/*#define NDEBUG*/
+#include <internal/debug.h>
 
-#include <sys/param.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "debug.h"
-#include "rtld.h"
-
-static Elf_Ehdr *get_elf_header (int, const char *);
-static int convert_prot(int);	/* Elf flags -> mmap protection */
-static int convert_flags(int); /* Elf flags -> mmap flags */
+#include <reactos/exeformat.h>
 
-/*
- * Map a shared object into memory.  The "fd" argument is a file descriptor,
- * which must be open on the object and positioned at its beginning.
- * The "path" argument is a pathname that is used only for error messages.
- *
- * The return value is a pointer to a newly-allocated Obj_Entry structure
- * for the shared object.  Returns NULL on failure.
- */
-Obj_Entry *
-map_object(int fd, const char *path, const struct stat *sb)
+#ifndef __ELF_WORD_SIZE
+#error __ELF_WORD_SIZE must be defined
+#endif
+
+#include <elf.h>
+
+/* TODO: Intsafe should be made into a library, as it's generally useful */
+static __inline BOOLEAN Intsafe_CanAddULongPtr
+(
+ IN ULONG_PTR Addend1,
+ IN ULONG_PTR Addend2
+)
 {
-    Obj_Entry *obj;
-    Elf_Ehdr *hdr;
-    int i;
-    Elf_Phdr *phdr;
-    Elf_Phdr *phlimit;
-    Elf_Phdr **segs;
-    int nsegs;
-    Elf_Phdr *phdyn;
-    Elf_Phdr *phphdr;
-    Elf_Phdr *phinterp;
-    Elf_Phdr *phtls;
-    caddr_t mapbase;
-    size_t mapsize;
-    Elf_Off base_offset;
-    Elf_Addr base_vaddr;
-    Elf_Addr base_vlimit;
-    caddr_t base_addr;
-    Elf_Off data_offset;
-    Elf_Addr data_vaddr;
-    Elf_Addr data_vlimit;
-    caddr_t data_addr;
-    int data_prot;
-    int data_flags;
-    Elf_Addr clear_vaddr;
-    caddr_t clear_addr;
-    caddr_t clear_page;
-    size_t nclear;
-    Elf_Addr bss_vaddr;
-    Elf_Addr bss_vlimit;
-    caddr_t bss_addr;
-
-    hdr = get_elf_header(fd, path);
-    if (hdr == NULL)
-	return (NULL);
+ return Addend1 <= (MAXULONG_PTR - Addend2);
+}
 
-    /*
-     * Scan the program header entries, and save key information.
-     *
-     * We rely on there being exactly two load segments, text and data,
-     * in that order.
-     */
-    phdr = (Elf_Phdr *) ((char *)hdr + hdr->e_phoff);
-    phlimit = phdr + hdr->e_phnum;
-    nsegs = -1;
-    phdyn = phphdr = phinterp = phtls = NULL;
-    segs = alloca(sizeof(segs[0]) * hdr->e_phnum);
-    while (phdr < phlimit) {
-	switch (phdr->p_type) {
-
-	case PT_INTERP:
-	    phinterp = phdr;
-	    break;
-
-	case PT_LOAD:
-	    segs[++nsegs] = phdr;
-    	    if (segs[nsegs]->p_align < PAGE_SIZE) {
-		_rtld_error("%s: PT_LOAD segment %d not page-aligned",
-		    path, nsegs);
-		return NULL;
-	    }
-	    break;
-
-	case PT_PHDR:
-	    phphdr = phdr;
-	    break;
-
-	case PT_DYNAMIC:
-	    phdyn = phdr;
-	    break;
-
-	case PT_TLS:
-	    phtls = phdr;
-	    break;
-	}
+#define Intsafe_CanAddSizeT Intsafe_CanAddULongPtr
 
-	++phdr;
-    }
-    if (phdyn == NULL) {
-	_rtld_error("%s: object is not dynamically-linked", path);
-	return NULL;
-    }
+static __inline BOOLEAN Intsafe_CanAddULong32
+(
+ IN ULONG Addend1,
+ IN ULONG Addend2
+)
+{
+ return Addend1 <= (MAXULONG - Addend2);
+}
 
-    if (nsegs < 0) {
-	_rtld_error("%s: too few PT_LOAD segments", path);
-	return NULL;
-    }
+static __inline BOOLEAN Intsafe_AddULong32
+(
+ OUT PULONG Result,
+ IN ULONG Addend1,
+ IN ULONG Addend2
+)
+{
+ if(!Intsafe_CanAddULong32(Addend1, Addend2))
+  return FALSE;
 
-    /*
-     * Map the entire address space of the object, to stake out our
-     * contiguous region, and to establish the base address for relocation.
-     */
-    base_offset = trunc_page(segs[0]->p_offset);
-    base_vaddr = trunc_page(segs[0]->p_vaddr);
-    base_vlimit = round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz);
-    mapsize = base_vlimit - base_vaddr;
-    base_addr = hdr->e_type == ET_EXEC ? (caddr_t) base_vaddr : NULL;
-
-    mapbase = mmap(base_addr, mapsize, convert_prot(segs[0]->p_flags),
-      convert_flags(segs[0]->p_flags), fd, base_offset);
-    if (mapbase == (caddr_t) -1) {
-	_rtld_error("%s: mmap of entire address space failed: %s",
-	  path, strerror(errno));
-	return NULL;
-    }
-    if (base_addr != NULL && mapbase != base_addr) {
-	_rtld_error("%s: mmap returned wrong address: wanted %p, got %p",
-	  path, base_addr, mapbase);
-	munmap(mapbase, mapsize);
-	return NULL;
-    }
+ *Result = Addend1 + Addend2;
+ return TRUE;
+}
 
-    for (i = 0; i <=  nsegs; i++) {
-	/* Overlay the segment onto the proper region. */
-	data_offset = trunc_page(segs[i]->p_offset);
-	data_vaddr = trunc_page(segs[i]->p_vaddr);
-	data_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_filesz);
-	data_addr = mapbase + (data_vaddr - base_vaddr);
-	data_prot = convert_prot(segs[i]->p_flags);
-	data_flags = convert_flags(segs[i]->p_flags) | MAP_FIXED;
-	/* Do not call mmap on the first segment - this is redundant */
-	if (i && mmap(data_addr, data_vlimit - data_vaddr, data_prot,
-	  data_flags, fd, data_offset) == (caddr_t) -1) {
-	    _rtld_error("%s: mmap of data failed: %s", path, strerror(errno));
-	    return NULL;
-	}
-
-	/* Clear any BSS in the last page of the segment. */
-	clear_vaddr = segs[i]->p_vaddr + segs[i]->p_filesz;
-	clear_addr = mapbase + (clear_vaddr - base_vaddr);
-	clear_page = mapbase + (trunc_page(clear_vaddr) - base_vaddr);
-	if ((nclear = data_vlimit - clear_vaddr) > 0) {
-	    /* Make sure the end of the segment is writable */
-	    if ((data_prot & PROT_WRITE) == 0 &&
-		-1 ==  mprotect(clear_page, PAGE_SIZE, data_prot|PROT_WRITE)) {
-			_rtld_error("%s: mprotect failed: %s", path,
-			    strerror(errno));
-			return NULL;
-	    }
-
-	    memset(clear_addr, 0, nclear);
-
-	    /* Reset the data protection back */
-	    if ((data_prot & PROT_WRITE) == 0)
-		 mprotect(clear_page, PAGE_SIZE, data_prot);
-	}
-
-	/* Overlay the BSS segment onto the proper region. */
-	bss_vaddr = data_vlimit;
-	bss_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_memsz);
-	bss_addr = mapbase +  (bss_vaddr - base_vaddr);
-	if (bss_vlimit > bss_vaddr) {	/* There is something to do */
-	    if (mmap(bss_addr, bss_vlimit - bss_vaddr, data_prot,
-		MAP_PRIVATE|MAP_FIXED|MAP_ANON, -1, 0) == (caddr_t) -1) {
-		    _rtld_error("%s: mmap of bss failed: %s", path,
-			strerror(errno));
-		return NULL;
-	    }
-	}
-    }
+static __inline BOOLEAN Intsafe_CanAddULong64
+(
+ IN ULONG64 Addend1,
+ IN ULONG64 Addend2
+)
+{
+ return Addend1 <= (((ULONG64)-1) - Addend2);
+}
 
-    obj = obj_new();
-    if (sb != NULL) {
-	obj->dev = sb->st_dev;
-	obj->ino = sb->st_ino;
-    }
-    obj->mapbase = mapbase;
-    obj->mapsize = mapsize;
-    obj->textsize = round_page(segs[0]->p_vaddr + segs[0]->p_memsz) -
-      base_vaddr;
-    obj->vaddrbase = base_vaddr;
-    obj->relocbase = mapbase - base_vaddr;
-    obj->dynamic = (const Elf_Dyn *) (obj->relocbase + phdyn->p_vaddr);
-    if (hdr->e_entry != 0)
-	obj->entry = (caddr_t) (obj->relocbase + hdr->e_entry);
-    if (phphdr != NULL) {
-	obj->phdr = (const Elf_Phdr *) (obj->relocbase + phphdr->p_vaddr);
-	obj->phsize = phphdr->p_memsz;
-    }
-    if (phinterp != NULL)
-	obj->interp = (const char *) (obj->relocbase + phinterp->p_vaddr);
-    if (phtls != NULL) {
-	tls_dtv_generation++;
-	obj->tlsindex = ++tls_max_index;
-	obj->tlssize = phtls->p_memsz;
-	obj->tlsalign = phtls->p_align;
-	obj->tlsinitsize = phtls->p_filesz;
-	obj->tlsinit = mapbase + phtls->p_vaddr;
-    }
-    return obj;
+static __inline BOOLEAN Intsafe_AddULong64
+(
+ OUT PULONG64 Result,
+ IN ULONG64 Addend1,
+ IN ULONG64 Addend2
+)
+{
+ if(!Intsafe_CanAddULong64(Addend1, Addend2))
+  return FALSE;
+
+ *Result = Addend1 + Addend2;
+ return TRUE;
 }
 
-static Elf_Ehdr *
-get_elf_header (int fd, const char *path)
+static __inline BOOLEAN Intsafe_CanMulULong32
+(
+ IN ULONG Factor1,
+ IN ULONG Factor2
+)
 {
-    static union {
-	Elf_Ehdr hdr;
-	char buf[PAGE_SIZE];
-    } u;
-    ssize_t nbytes;
+ return Factor1 <= (MAXULONG / Factor2);
+}
 
-    if ((nbytes = read(fd, u.buf, PAGE_SIZE)) == -1) {
-	_rtld_error("%s: read error: %s", path, strerror(errno));
-	return NULL;
-    }
+static __inline BOOLEAN Intsafe_MulULong32
+(
+ OUT PULONG Result,
+ IN ULONG Factor1,
+ IN ULONG Factor2
+)
+{
+ if(!Intsafe_CanMulULong32(Factor1, Factor2))
+  return FALSE;
 
-    /* Make sure the file is valid */
-    if (nbytes < (ssize_t)sizeof(Elf_Ehdr) || !IS_ELF(u.hdr)) {
-	_rtld_error("%s: invalid file format", path);
-	return NULL;
-    }
-    if (u.hdr.e_ident[EI_CLASS] != ELF_TARG_CLASS
-      || u.hdr.e_ident[EI_DATA] != ELF_TARG_DATA) {
-	_rtld_error("%s: unsupported file layout", path);
-	return NULL;
-    }
-    if (u.hdr.e_ident[EI_VERSION] != EV_CURRENT
-      || u.hdr.e_version != EV_CURRENT) {
-	_rtld_error("%s: unsupported file version", path);
-	return NULL;
-    }
-    if (u.hdr.e_type != ET_EXEC && u.hdr.e_type != ET_DYN) {
-	_rtld_error("%s: unsupported file type", path);
-	return NULL;
-    }
-    if (u.hdr.e_machine != ELF_TARG_MACH) {
-	_rtld_error("%s: unsupported machine", path);
-	return NULL;
-    }
+ *Result = Factor1 * Factor2;
+ return TRUE;
+}
 
-    /*
-     * We rely on the program header being in the first page.  This is
-     * not strictly required by the ABI specification, but it seems to
-     * always true in practice.  And, it simplifies things considerably.
-     */
-    if (u.hdr.e_phentsize != sizeof(Elf_Phdr)) {
-	_rtld_error(
-	  "%s: invalid shared object: e_phentsize != sizeof(Elf_Phdr)", path);
-	return NULL;
-    }
-    if (u.hdr.e_phoff + u.hdr.e_phnum * sizeof(Elf_Phdr) > (size_t)nbytes) {
-	_rtld_error("%s: program header too large", path);
-	return NULL;
-    }
+static __inline BOOLEAN Intsafe_CanOffsetPointer
+(
+ IN CONST VOID * Pointer,
+ IN SIZE_T Offset
+)
+{
+ /* FIXME: (PVOID)MAXULONG_PTR isn't necessarily a valid address */
+ return Intsafe_CanAddULongPtr((ULONG_PTR)Pointer, Offset);
+}
+
+#if __ELF_WORD_SIZE == 32
+#define ElfFmtpAddSize Intsafe_AddULong32
+#define ElfFmtpReadAddr ElfFmtpReadULong
+#define ElfFmtpReadOff  ElfFmtpReadULong
+#define ElfFmtpSafeReadAddr ElfFmtpSafeReadULong
+#define ElfFmtpSafeReadOff  ElfFmtpSafeReadULong
+#define ElfFmtpSafeReadSize ElfFmtpSafeReadULong
+#elif __ELF_WORD_SIZE == 64
+#define ElfFmtpAddSize Intsafe_AddULong64
+#define ElfFmtpReadAddr ElfFmtpReadULong64
+#define ElfFmtpReadOff  ElfFmtpReadULong64
+#define ElfFmtpSafeReadAddr ElfFmtpSafeReadULong64
+#define ElfFmtpSafeReadOff  ElfFmtpSafeReadULong64
+#define ElfFmtpSafeReadSize ElfFmtpSafeReadULong64
+#endif
+
+/* TODO: these are standard DDK/PSDK macros */
+#define RtlRetrieveUlonglong(DST_, SRC_) \
+ (RtlCopyMemory((DST_), (SRC_), sizeof(ULONG64)))
+
+#ifndef RTL_FIELD_SIZE
+#define RTL_FIELD_SIZE(TYPE_, FIELD_) (sizeof(((TYPE_ *)0)->FIELD_))
+#endif
+
+#ifndef RTL_SIZEOF_THROUGH_FIELD
+#define RTL_SIZEOF_THROUGH_FIELD(TYPE_, FIELD_) \
+ (FIELD_OFFSET(TYPE_, FIELD_) + RTL_FIELD_SIZE(TYPE_, FIELD_))
+#endif
+
+#ifndef RTL_CONTAINS_FIELD
+#define RTL_CONTAINS_FIELD(P_, SIZE_, FIELD_) \
+ ((((char *)(P_)) + (SIZE_)) > (((char *)(&((P_)->FIELD_))) + sizeof((P_)->FIELD_)))
+#endif
+
+#define ELFFMT_FIELDS_EQUAL(TYPE1_, TYPE2_, FIELD_) \
+ ( \
+  (FIELD_OFFSET(TYPE1_, FIELD_) == FIELD_OFFSET(TYPE2_, FIELD_)) && \
+  (RTL_FIELD_SIZE(TYPE1_, FIELD_) == RTL_FIELD_SIZE(TYPE2_, FIELD_)) \
+ )
+
+#define ELFFMT_MAKE_ULONG64(BYTE1_, BYTE2_, BYTE3_, BYTE4_, BYTE5_, BYTE6_, BYTE7_, BYTE8_) \
+ ( \
+  (((ULONG64)ELFFMT_MAKE_ULONG(BYTE1_, BYTE2_, BYTE3_, BYTE4_)) <<  0) | \
+  (((ULONG64)ELFFMT_MAKE_ULONG(BYTE5_, BYTE6_, BYTE7_, BYTE8_)) << 32) \
+ )
+
+#define ELFFMT_MAKE_ULONG(BYTE1_, BYTE2_, BYTE3_, BYTE4_) \
+ ( \
+  (((ULONG)ELFFMT_MAKE_USHORT(BYTE1_, BYTE2_)) <<  0) | \
+  (((ULONG)ELFFMT_MAKE_USHORT(BYTE3_, BYTE4_)) << 16) \
+ )
+
+#define ELFFMT_MAKE_USHORT(BYTE1_, BYTE2_) \
+ ( \
+  (((USHORT)(BYTE1_)) << 0) | \
+  (((USHORT)(BYTE2_)) << 8) \
+ )
+
+static __inline ULONG64 ElfFmtpReadULong64
+(
+ IN ULONG64 Input,
+ IN ULONG DataType
+)
+{
+ PBYTE p;
+
+ if(DataType == ELF_TARG_DATA)
+  return Input;
+
+ p = (PBYTE)&Input;
+
+ switch(DataType)
+ {
+  case ELFDATA2LSB: return ELFFMT_MAKE_ULONG64(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+  case ELFDATA2MSB: return ELFFMT_MAKE_ULONG64(p[7], p[6], p[5], p[4], p[3], p[2], p[1], p[0]);
+ }
 
-    return (&u.hdr);
+ ASSERT(FALSE);
+ return (ULONG64)-1;
 }
 
-void
-obj_free(Obj_Entry *obj)
+static __inline ULONG ElfFmtpReadULong
+(
+ IN ULONG Input,
+ IN ULONG DataType
+)
 {
-    Objlist_Entry *elm;
+ PBYTE p;
 
-    free(obj->path);
-    while (obj->needed != NULL) {
-	Needed_Entry *needed = obj->needed;
-	obj->needed = needed->next;
-	free(needed);
-    }
-    while (!STAILQ_EMPTY(&obj->dldags)) {
-	elm = STAILQ_FIRST(&obj->dldags);
-	STAILQ_REMOVE_HEAD(&obj->dldags, link);
-	free(elm);
-    }
-    while (!STAILQ_EMPTY(&obj->dagmembers)) {
-	elm = STAILQ_FIRST(&obj->dagmembers);
-	STAILQ_REMOVE_HEAD(&obj->dagmembers, link);
-	free(elm);
-    }
-    free(obj->origin_path);
-    free(obj->priv);
-    free(obj);
+ if(DataType == ELF_TARG_DATA)
+  return Input;
+
+ p = (PBYTE)&Input;
+
+ switch(DataType)
+ {
+  case ELFDATA2LSB: return ELFFMT_MAKE_ULONG(p[0], p[1], p[2], p[3]);
+  case ELFDATA2MSB: return ELFFMT_MAKE_ULONG(p[3], p[2], p[1], p[0]);
+ }
+
+ ASSERT(FALSE);
+ return (ULONG)-1;
 }
 
-Obj_Entry *
-obj_new(void)
+static __inline USHORT ElfFmtpReadUShort
+(
+ IN USHORT Input,
+ IN ULONG DataType
+)
 {
-    Obj_Entry *obj;
+ PBYTE p;
 
-    obj = CNEW(Obj_Entry);
-    STAILQ_INIT(&obj->dldags);
-    STAILQ_INIT(&obj->dagmembers);
-    return obj;
+ if(DataType == ELF_TARG_DATA)
+  return Input;
+
+ p = (PBYTE)&Input;
+
+ switch(DataType)
+ {
+  case ELFDATA2LSB: return ELFFMT_MAKE_USHORT(p[0], p[1]);
+  case ELFDATA2MSB: return ELFFMT_MAKE_USHORT(p[1], p[0]);
+ }
+
+ ASSERT(FALSE);
+ return (USHORT)-1;
 }
 
-/*
- * Given a set of ELF protection flags, return the corresponding protection
- * flags for MMAP.
- */
-static int
-convert_prot(int elfflags)
+static __inline ULONG64 ElfFmtpSafeReadULong64
+(
+ IN CONST ULONG64 * Input,
+ IN ULONG DataType
+)
+{
+ PBYTE p;
+ ULONG nSafeInput;
+
+ RtlRetrieveUlonglong(&nSafeInput, Input);
+
+ p = (PBYTE)&nSafeInput;
+
+ switch(DataType)
+ {
+  case ELFDATA2LSB: return ELFFMT_MAKE_ULONG64(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+  case ELFDATA2MSB: return ELFFMT_MAKE_ULONG64(p[7], p[6], p[5], p[4], p[3], p[2], p[1], p[0]);
+ }
+
+ ASSERT(FALSE);
+ return (ULONG64)-1;
+}
+
+static __inline ULONG ElfFmtpSafeReadULong
+(
+ IN CONST ULONG * Input,
+ IN ULONG DataType
+)
+{
+ PBYTE p;
+ ULONG nSafeInput;
+
+ RtlRetrieveUlong(&nSafeInput, Input);
+
+ if(DataType == ELF_TARG_DATA)
+  return nSafeInput;
+
+ p = (PBYTE)&nSafeInput;
+
+ switch(DataType)
+ {
+  case ELFDATA2LSB: return ELFFMT_MAKE_ULONG(p[0], p[1], p[2], p[3]);
+  case ELFDATA2MSB: return ELFFMT_MAKE_ULONG(p[3], p[2], p[1], p[0]);
+ }
+
+ ASSERT(FALSE);
+ return (ULONG)-1;
+}
+
+static __inline BOOLEAN ElfFmtpIsPowerOf2(IN Elf_Addr Number)
+{
+ if(Number == 0)
+  return FALSE;
+
+ while((Number % 2) == 0)
+  Number /= 2;
+
+ return Number == 1;
+}
+
+static __inline Elf_Addr ElfFmtpModPow2
+(
+ IN Elf_Addr Address,
+ IN Elf_Addr Alignment
+)
+{
+ ASSERT(sizeof(Elf_Addr) == sizeof(Elf_Size));
+ ASSERT(sizeof(Elf_Addr) == sizeof(Elf_Off));
+ ASSERT(ElfFmtpIsPowerOf2(Alignment));
+ return Address & (Alignment - 1);
+}
+
+static __inline Elf_Addr ElfFmtpAlignDown
+(
+ IN Elf_Addr Address,
+ IN Elf_Addr Alignment
+)
 {
-    int prot = 0;
-    if (elfflags & PF_R)
-	prot |= PROT_READ;
-    if (elfflags & PF_W)
-	prot |= PROT_WRITE;
-    if (elfflags & PF_X)
-	prot |= PROT_EXEC;
-    return prot;
+ ASSERT(sizeof(Elf_Addr) == sizeof(Elf_Size));
+ ASSERT(sizeof(Elf_Addr) == sizeof(Elf_Off));
+ ASSERT(ElfFmtpIsPowerOf2(Alignment));
+ return Address & ~(Alignment - 1);
 }
 
-static int
-convert_flags(int elfflags)
+static __inline BOOLEAN ElfFmtpAlignUp
+(
+ OUT Elf_Addr * AlignedAddress,
+ IN Elf_Addr Address,
+ IN Elf_Addr Alignment
+)
 {
-    int flags = MAP_PRIVATE; /* All mappings are private */
+ Elf_Addr nExcess = ElfFmtpModPow2(Address, Alignment);
 
+ if(nExcess == 0)
+ {
+  *AlignedAddress = Address;
+  return nExcess == 0;
+ }
+ else
+  return ElfFmtpAddSize(AlignedAddress, Address, Alignment - nExcess);
+}
+
+/*
+ References:
+  [1] Tool Interface Standards (TIS) Committee, "Executable and Linking Format
+      (ELF) Specification", Version 1.2
+*/
+NTSTATUS NTAPI
+#if __ELF_WORD_SIZE == 32
+Elf32FmtCreateSection
+#elif __ELF_WORD_SIZE == 64
+Elf64FmtCreateSection
+#endif
+(
+ IN CONST VOID * FileHeader,
+ IN SIZE_T FileHeaderSize,
+ IN PVOID File,
+ OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
+ OUT PULONG Flags,
+ IN PEXEFMT_CB_READ_FILE ReadFileCb,
+ IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
+)
+{
+ NTSTATUS nStatus;
+ const Elf_Ehdr * pehHeader;
+ const Elf_Phdr * pphPHdrs;
+ BOOLEAN fPageAligned;
+ ULONG nData;
+ ULONG nPHdrCount;
+ ULONG cbPHdrSize;
+ Elf_Off cbPHdrOffset;
+ PVOID pBuffer;
+ PMM_SECTION_SEGMENT pssSegments;
+ Elf_Addr nImageBase;
+ Elf_Addr nEntryPoint;
+ ULONG nPrevVirtualEndOfSegment;
+ ULONG i;
+ ULONG j;
+
+ (void)Intsafe_AddULong64;
+ (void)Intsafe_MulULong32;
+ (void)ElfFmtpReadULong64;
+ (void)ElfFmtpSafeReadULong64;
+ (void)ElfFmtpReadULong;
+
+#define DIE(ARGS_) { DPRINT ARGS_; goto l_Return; }
+
+ pBuffer = NULL;
+
+ nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
+ /* Ensure the file contains the full header */
+ /*
+  EXEFMT_LOAD_HEADER_SIZE is 8KB: enough to contain an ELF header (at least in
+  all the classes defined as of December 2004). If FileHeaderSize is less than
+  sizeof(Elf_Ehdr), it means the file itself is small enough not to contain a
+  full ELF header
+ */
+ ASSERT(sizeof(Elf_Ehdr) <= EXEFMT_LOAD_HEADER_SIZE);
+
+ if(FileHeaderSize < sizeof(Elf_Ehdr))
+  DIE(("The file is truncated, doesn't contain the full header\n"));
+
+ pehHeader = FileHeader;
+ ASSERT(((ULONG_PTR)pehHeader % TYPE_ALIGNMENT(Elf_Ehdr)) == 0);
+
+ nData = pehHeader->e_ident[EI_DATA];
+
+ /* Validate the header */
+ if(ElfFmtpReadUShort(pehHeader->e_ehsize, nData) < sizeof(Elf_Ehdr))
+  DIE(("Inconsistent value for e_ehsize\n"));
+
+ /* Calculate size and offset of the program headers */
+ cbPHdrSize = ElfFmtpReadUShort(pehHeader->e_phentsize, nData);
+
+ if(cbPHdrSize != sizeof(Elf_Phdr))
+  DIE(("Inconsistent value for e_phentsize\n"));
+
+ /* MAXUSHORT * MAXUSHORT < MAXULONG */
+ nPHdrCount = ElfFmtpReadUShort(pehHeader->e_phnum, nData);
+ ASSERT(Intsafe_CanMulULong32(cbPHdrSize, nPHdrCount));
+ cbPHdrSize *= nPHdrCount;
+
+ cbPHdrOffset = ElfFmtpReadOff(pehHeader->e_phoff, nData);
+
+ /* The initial header doesn't contain the program headers */
+ if(cbPHdrOffset > FileHeaderSize || cbPHdrSize > (FileHeaderSize - cbPHdrOffset))
+ {
+  NTSTATUS nReadStatus;
+  LARGE_INTEGER lnOffset;
+  PVOID pData;
+  ULONG cbReadSize;
+
+  /* Will worry about this when ELF128 comes */
+  ASSERT(sizeof(cbPHdrOffset) <= sizeof(lnOffset.QuadPart));
+
+  lnOffset.QuadPart = (LONG64)cbPHdrOffset;
+
+  /*
+   We can't support executable files larger than 8 Exabytes - it's a limitation
+   of the I/O system (only 63-bit offsets are supported). Quote:
+
+    [...] the total amount of printed material in the world is estimated to be
+    around a fifth of an exabyte. [...] [Source: Wikipedia]
+  */
+  if(lnOffset.u.HighPart < 0)
+   DIE(("The program header is too far into the file\n"));
+
+  nReadStatus = ReadFileCb
+  (
+   File,
+   &lnOffset,
+   cbPHdrSize,
+   &pData,
+   &pBuffer,
+   &cbReadSize
+  );
+
+  if(!NT_SUCCESS(nReadStatus))
+  {
+   nStatus = nReadStatus;
+   DIE(("ReadFile failed, status %08X\n", nStatus));
+  }
+
+  ASSERT(pData);
+  ASSERT(pBuffer);
+  ASSERT(Intsafe_CanOffsetPointer(pData, cbReadSize));
+
+  if(cbReadSize < cbPHdrSize)
+   DIE(("The file didn't contain the program headers\n"));
+
+  /* Force the buffer to be aligned */
+  if((ULONG_PTR)pData % TYPE_ALIGNMENT(Elf_Phdr))
+  {
+   ASSERT(((ULONG_PTR)pBuffer % TYPE_ALIGNMENT(Elf_Phdr)) == 0);
+   RtlMoveMemory(pBuffer, pData, cbPHdrSize);
+   pphPHdrs = pBuffer;
+  }
+  else
+   pphPHdrs = pData;
+ }
+ else
+ {
+  ASSERT(Intsafe_CanAddSizeT(cbPHdrOffset, 0));
+  ASSERT(Intsafe_CanOffsetPointer(FileHeader, cbPHdrOffset));
+  pphPHdrs = (PVOID)((ULONG_PTR)FileHeader + (ULONG_PTR)cbPHdrOffset);
+ }
+
+ /* Allocate the segments */
+ pssSegments = AllocateSegmentsCb(nPHdrCount);
+
+ if(pssSegments == NULL)
+ {
+  nStatus = STATUS_INSUFFICIENT_RESOURCES;
+  DIE(("Out of memory\n"));
+ }
+
+ ImageSectionObject->Segments = pssSegments;
+
+ fPageAligned = TRUE;
+
+ /* Fill in the segments */
+ for(i = 0, j = 0; i < nPHdrCount; ++ i)
+ {
+  switch(ElfFmtpSafeReadULong(&pphPHdrs[i].p_type, nData))
+  {
+   case PT_LOAD:
+   {
+    static const ULONG ProgramHeaderFlagsToProtect[8] =
+    {
+     PAGE_NOACCESS,          /* 0 */
+     PAGE_EXECUTE_READ,      /* PF_X */
+     PAGE_READWRITE,         /* PF_W */
+     PAGE_EXECUTE_READWRITE, /* PF_X | PF_W */
+     PAGE_READONLY,          /* PF_R */
+     PAGE_EXECUTE_READ,      /* PF_X | PF_R */
+     PAGE_READWRITE,         /* PF_W | PF_R */
+     PAGE_EXECUTE_READWRITE  /* PF_X | PF_W | PF_R */
+    };
+
+    Elf_Size nAlignment;
+    Elf_Off nFileOffset;
+    Elf_Addr nVirtualAddr;
+    Elf_Size nAdj;
+    Elf_Size nVirtualSize;
+    Elf_Size nFileSize;
+
+    ASSERT(j <= nPHdrCount);
+
+    /* Retrieve and validate the segment alignment */
+    nAlignment = ElfFmtpSafeReadSize(&pphPHdrs[i].p_align, nData);
+
+    if(nAlignment == 0)
+     nAlignment = 1;
+    else if(!ElfFmtpIsPowerOf2(nAlignment))
+     DIE(("Alignment of loadable segment isn't a power of 2\n"));
+
+    if(nAlignment < PAGE_SIZE)
+     fPageAligned = FALSE;
+
+    /* Retrieve the addresses and calculate the adjustment */
+    nFileOffset = ElfFmtpSafeReadOff(&pphPHdrs[i].p_offset, nData);
+    nVirtualAddr = ElfFmtpSafeReadAddr(&pphPHdrs[i].p_vaddr, nData);
+
+    nAdj = ElfFmtpModPow2(nFileOffset, nAlignment);
+
+    if(nAdj != ElfFmtpModPow2(nVirtualAddr, nAlignment))
+     DIE(("File and memory address of loadable segment not congruent modulo alignment\n"));
+
+    /* Retrieve, adjust and align the file size and memory size */
+    if(!ElfFmtpAddSize(&nFileSize, ElfFmtpSafeReadSize(&pphPHdrs[i].p_filesz, nData), nAdj))
+     DIE(("Can't adjust the file size of loadable segment\n"));
+
+    if(!ElfFmtpAddSize(&nVirtualSize, ElfFmtpSafeReadSize(&pphPHdrs[i].p_memsz, nData), nAdj))
+     DIE(("Can't adjust the memory size of lodable segment\n"));
+
+    if(!ElfFmtpAlignUp(&nVirtualSize, nVirtualSize, nAlignment))
+     DIE(("Can't align the memory size of lodable segment\n"));
+
+    if(nFileSize > nVirtualSize)
+     nFileSize = nVirtualSize;
+
+    if(nVirtualSize > MAXULONG)
+     DIE(("Virtual image larger than 4GB\n"));
+
+    ASSERT(nFileSize <= MAXULONG);
+
+    pssSegments[j].Length = (ULONG)(nVirtualSize & 0xFFFFFFFF);
+    pssSegments[j].RawLength = (ULONG)(nFileSize & 0xFFFFFFFF);
+
+    /* File offset */
+    nFileOffset = ElfFmtpAlignDown(nFileOffset, nAlignment);
+
+#if __ELF_WORD_SIZE >= 64
+    ASSERT(sizeof(nFileOffset) == sizeof(LONG64));
+
+    if(((LONG64)nFileOffset) < 0)
+     DIE(("File offset of loadable segment is too large\n"));
+#endif
+
+    pssSegments[j].FileOffset = (LONG64)nFileOffset;
+
+    /* Virtual address */
+    nVirtualAddr = ElfFmtpAlignDown(nVirtualAddr, nAlignment);
+
+    if(j == 0)
+    {
+     /* First segment: its address is the base address of the image */
+     nImageBase = nVirtualAddr;
+     pssSegments[j].VirtualAddress = 0;
+
+     /* Several places make this assumption */
+     if(pssSegments[j].FileOffset != 0)
+      DIE(("First loadable segment doesn't contain the ELF header\n"));
+    }
+    else
+    {
+     Elf_Size nVirtualOffset;
+
+     /* Other segment: store the offset from the base address */
+     if(nVirtualAddr <= nImageBase)
+      DIE(("Loadable segments are not sorted\n"));
+
+     nVirtualOffset = nVirtualAddr - nImageBase;
+
+     if(nVirtualOffset > MAXULONG)
+      DIE(("Virtual image larger than 4GB\n"));
+
+     pssSegments[j].VirtualAddress = (ULONG)(nVirtualOffset & 0xFFFFFFFF);
+
+     if(pssSegments[j].VirtualAddress != nPrevVirtualEndOfSegment)
+      DIE(("Loadable segments are not sorted and contiguous\n"));
+    }
+
+    /* Memory protection */
+    pssSegments[j].Protection = ProgramHeaderFlagsToProtect
+    [
+     ElfFmtpSafeReadULong(&pphPHdrs[i].p_flags, nData) & (PF_R | PF_W | PF_X)
+    ];
+
+    /* Characteristics */
     /*
-     * Readonly mappings are marked "MAP_NOCORE", because they can be
-     * reconstructed by a debugger.
-     */
-    if (!(elfflags & PF_W))
-	flags |= MAP_NOCORE;
-    return flags;
+     TODO: need to add support for the shared, non-pageable, non-cacheable and
+     discardable attributes. This involves extensions to the ELF format, so it's
+     nothing to be taken lightly
+    */
+    if(pssSegments[j].Protection & PAGE_IS_EXECUTABLE)
+    {
+     ImageSectionObject->Executable = TRUE;
+     pssSegments[j].Characteristics = IMAGE_SCN_CNT_CODE;
+    }
+    else if(pssSegments[j].RawLength == 0)
+     pssSegments[j].Characteristics = IMAGE_SCN_CNT_UNINITIALIZED_DATA;
+    else
+     pssSegments[j].Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA;
+
+    /* Copy-on-write */
+    pssSegments[j].WriteCopy = TRUE;
+
+    if(!Intsafe_AddULong32(&nPrevVirtualEndOfSegment, pssSegments[j].VirtualAddress, pssSegments[j].Length))
+     DIE(("Virtual image larger than 4GB\n"));
+
+    ++ j;
+    break;
+   }
+  }
+ }
+
+ if(j == 0)
+  DIE(("No loadable segments\n"));
+
+ ImageSectionObject->NrSegments = j;
+
+ *Flags =
+  EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED |
+  EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP;
+
+ if(fPageAligned)
+  *Flags |= EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED;
[truncated at 1000 lines; 49 more skipped]

reactos/ntoskrnl/mm
pe.c 1.1.2.4 -> 1.1.2.5
diff -u -r1.1.2.4 -r1.1.2.5
--- pe.c	18 Dec 2004 02:36:09 -0000	1.1.2.4
+++ pe.c	30 Dec 2004 01:59:59 -0000	1.1.2.5
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: pe.c,v 1.1.2.4 2004/12/18 02:36:09 hyperion Exp $
+/* $Id: pe.c,v 1.1.2.5 2004/12/30 01:59:59 hyperion Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/mm/pe.c
@@ -25,13 +25,17 @@
  * UPDATE HISTORY:
  *                  2004-12-06 Created
  *                  2004-12-09 Compiles
+ *                  2004-12-26 Actually works, several checks relaxed to support
+ *                             the majority of existing executables, corrected
+ *                             the alignment helper functions, debug messages to
+ *                             explain failure.
  */
 
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
 
-/*#define NDEBUG*/
+#define NDEBUG
 #include <internal/debug.h>
 
 #include <reactos/exeformat.h>
@@ -46,18 +50,22 @@
  PAGE_READONLY,          /* 5 = READABLE, SHARED */
  PAGE_EXECUTE_READ,      /* 6 = READABLE, EXECUTABLE */
  PAGE_EXECUTE_READ,      /* 7 = READABLE, EXECUTABLE, SHARED */
- PAGE_WRITECOPY,         /* 8 = WRITABLE */
+ /*
+  * FIXME? do we really need the WriteCopy field in segments? can't we use
+  * PAGE_WRITECOPY here?
+  */
+ PAGE_READWRITE,         /* 8 = WRITABLE */
  PAGE_READWRITE,         /* 9 = WRITABLE, SHARED */
- PAGE_EXECUTE_WRITECOPY, /* 10 = WRITABLE, EXECUTABLE */
+ PAGE_EXECUTE_READWRITE, /* 10 = WRITABLE, EXECUTABLE */
  PAGE_EXECUTE_READWRITE, /* 11 = WRITABLE, EXECUTABLE, SHARED */
- PAGE_WRITECOPY,         /* 12 = WRITABLE, READABLE */
+ PAGE_READWRITE,         /* 12 = WRITABLE, READABLE */
  PAGE_READWRITE,         /* 13 = WRITABLE, READABLE, SHARED */
- PAGE_EXECUTE_WRITECOPY, /* 14 = WRITABLE, READABLE, EXECUTABLE */
+ PAGE_EXECUTE_READWRITE, /* 14 = WRITABLE, READABLE, EXECUTABLE */
  PAGE_EXECUTE_READWRITE, /* 15 = WRITABLE, READABLE, EXECUTABLE, SHARED */
 };
 
 /* TODO: Intsafe should be made into a library, as it's generally useful */
-BOOLEAN FASTCALL Intsafe_CanAddULongPtr
+static __inline BOOLEAN Intsafe_CanAddULongPtr
 (
  IN ULONG_PTR Addend1,
  IN ULONG_PTR Addend2
@@ -66,44 +74,7 @@
  return Addend1 <= (MAXULONG_PTR - Addend2);
 }
 
-BOOLEAN FASTCALL Intsafe_AddULongPtr
-(
- OUT PULONG_PTR Result,
- IN ULONG_PTR Addend1,
- IN ULONG_PTR Addend2
-)
-{
- if(!Intsafe_CanAddULongPtr(Addend1, Addend2))
-  return FALSE;
-
- *Result = Addend1 + Addend2;
- return TRUE;
-}
-
-BOOLEAN FASTCALL Intsafe_CanMulULongPtr
-(
- IN ULONG_PTR Factor1,
- IN ULONG_PTR Factor2
-)
-{
- return Factor1 <= (MAXULONG_PTR / Factor2);
-}
-
-BOOLEAN FASTCALL Intsafe_MulULongPtr
-(
- OUT PULONG_PTR Result,
- IN ULONG_PTR Factor1,
- IN ULONG_PTR Factor2
-)
-{
- if(!Intsafe_CanMulULongPtr(Factor1, Factor2))
-  return FALSE;
-
- *Result = Factor1 * Factor2;
- return TRUE;
-}
-
-BOOLEAN FASTCALL Intsafe_CanAddULong32
+static __inline BOOLEAN Intsafe_CanAddULong32
 (
  IN ULONG Addend1,
  IN ULONG Addend2
@@ -112,7 +83,7 @@
  return Addend1 <= (MAXULONG - Addend2);
 }
 
-BOOLEAN FASTCALL Intsafe_AddULong32
+static __inline BOOLEAN Intsafe_AddULong32
 (
  OUT PULONG Result,
  IN ULONG Addend1,
@@ -126,7 +97,7 @@
  return TRUE;
 }
 
-BOOLEAN FASTCALL Intsafe_CanMulULong32
+static __inline BOOLEAN Intsafe_CanMulULong32
 (
  IN ULONG Factor1,
  IN ULONG Factor2
@@ -135,21 +106,7 @@
  return Factor1 <= (MAXULONG / Factor2);
 }
 
-BOOLEAN FASTCALL Intsafe_MulULong32
-(
- OUT PULONG Result,
- IN ULONG Factor1,
- IN ULONG Factor2
-)
-{
- if(!Intsafe_CanMulULong32(Factor1, Factor2))
-  return FALSE;
-
- *Result = Factor1 * Factor2;
- return TRUE;
-}
-
-BOOLEAN FASTCALL Intsafe_CanOffsetPointer
+static __inline BOOLEAN Intsafe_CanOffsetPointer
 (
  IN CONST VOID * Pointer,
  IN SIZE_T Offset
@@ -174,7 +131,7 @@
  ((((char *)(P_)) + (SIZE_)) > (((char *)(&((P_)->FIELD_))) + sizeof((P_)->FIELD_)))
 #endif
 
-BOOLEAN FASTCALL IsPowerOf2(IN ULONG Number)
+static __inline BOOLEAN IsPowerOf2(IN ULONG Number)
 {
  if(Number == 0)
   return FALSE;
@@ -185,25 +142,25 @@
  return Number == 1;
 }
 
-ULONG FASTCALL GetExcess(IN ULONG Address, IN ULONG Alignment)
+static __inline ULONG ModPow2(IN ULONG Address, IN ULONG Alignment)
 {
  ASSERT(IsPowerOf2(Alignment));
  return Address & (Alignment - 1);
 }
 
-BOOLEAN FASTCALL IsAligned(IN ULONG Address, IN ULONG Alignment)
+static __inline BOOLEAN IsAligned(IN ULONG Address, IN ULONG Alignment)
 {
- return GetExcess(Address, Alignment) == 0;
+ return ModPow2(Address, Alignment) == 0;
 }
 
-BOOLEAN FASTCALL AlignUp
+static __inline BOOLEAN AlignUp
 (
  OUT PULONG AlignedAddress,
  IN ULONG Address,
  IN ULONG Alignment
 )
 {
- ULONG nExcess = GetExcess(Address, Alignment);
+ ULONG nExcess = ModPow2(Address, Alignment);
 
  if(nExcess == 0)
  {
@@ -214,6 +171,12 @@
   return Intsafe_AddULong32(AlignedAddress, Address, Alignment - nExcess);
 }
 
+#define PEFMT_FIELDS_EQUAL(TYPE1_, TYPE2_, FIELD_) \
+ ( \
+  (FIELD_OFFSET(TYPE1_, FIELD_) == FIELD_OFFSET(TYPE2_, FIELD_)) && \
+  (RTL_FIELD_SIZE(TYPE1_, FIELD_) == RTL_FIELD_SIZE(TYPE2_, FIELD_)) \
+ )
+
 /*
  References:
   [1] Microsoft Corporation, "Microsoft Portable Executable and Common Object
@@ -223,7 +186,7 @@
 (
  IN CONST VOID * FileHeader,
  IN SIZE_T FileHeaderSize,
- IN PFILE_OBJECT File,
+ IN PVOID File,
  OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
  OUT PULONG Flags,
  IN PEXEFMT_CB_READ_FILE ReadFileCb,
@@ -311,7 +274,7 @@
   (UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0
  )
  {
-  SIZE_T cbNtHeaderSize;
+  ULONG cbNtHeaderSize;
   ULONG cbReadSize;
   PVOID pData;
 
@@ -340,14 +303,14 @@
 
   /* the buffer doesn't contain the file header */
   if(cbReadSize < RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader))
-   DIE(("The file doesn't contain the PE file header"));
+   DIE(("The file doesn't contain the PE file header\n"));
 
   pinhNtHeader = pData;
 
   /* object still not aligned: copy it to the beginning of the buffer */
-  if((UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) != 0)
+  if((UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0)
   {
-   ASSERT((UINT_PTR)pBuffer % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) == 0);
+   ASSERT((UINT_PTR)pBuffer % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) == 0);
    RtlMoveMemory(pBuffer, pData, cbReadSize);
    pinhNtHeader = pBuffer;
   }
@@ -392,6 +355,8 @@
 
  nStatus = STATUS_INVALID_IMAGE_FORMAT;
 
+ ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, Magic));
+
  if(!RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, Magic))
   DIE(("The optional header doesn't contain the Magic field, SizeOfOptionalHeader is %X\n", cbOptHeaderSize));
 
@@ -407,6 +372,9 @@
    DIE(("Unrecognized optional header, Magic is %X\n", piohOptHeader->Magic));
  }
 
+ ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SectionAlignment));
+ ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, FileAlignment));
+
  if
  (
   RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SectionAlignment) &&
@@ -457,9 +425,9 @@
   /* PE32+ */
   case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
   {
-   PIMAGE_OPTIONAL_HEADER64 pioh64OptHeader;
+   const IMAGE_OPTIONAL_HEADER64 * pioh64OptHeader;
 
-   pioh64OptHeader = (PIMAGE_OPTIONAL_HEADER64)piohOptHeader;
+   pioh64OptHeader = (const IMAGE_OPTIONAL_HEADER64 *)piohOptHeader;
 
    if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, ImageBase))
    {
@@ -493,10 +461,10 @@
  if((ULONG_PTR)ImageSectionObject->ImageBase % 0x10000)
   DIE(("ImageBase is not aligned on a 64KB boundary"));
 
- /*
-  ASSUME: all the fields used here have the same offset and size in both
-  IMAGE_OPTIONAL_HEADER32 and IMAGE_OPTIONAL_HEADER64
- */
+ ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, Subsystem));
+ ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MinorSubsystemVersion));
+ ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, MajorSubsystemVersion));
+
  if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, Subsystem))
  {
   ImageSectionObject->Subsystem = piohOptHeader->Subsystem;
@@ -512,9 +480,13 @@
   }
  }
 
+ ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, AddressOfEntryPoint));
+
  if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint))
   ImageSectionObject->EntryPoint = piohOptHeader->AddressOfEntryPoint;
 
+ ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SizeOfCode));
+
  if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfCode))
   ImageSectionObject->Executable = piohOptHeader->SizeOfCode != 0;
  else
@@ -551,6 +523,8 @@
  if(!Intsafe_AddULong32(&cbSectionHeadersOffsetSize, cbSectionHeadersOffset, cbSectionHeadersSize))
   DIE(("Section headers too large\n"));
 
+ ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, SizeOfHeaders));
+
  /* size of the executable's headers */
  if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfHeaders))
  {
@@ -660,7 +634,8 @@
  pssSegments[0].Length = nPrevVirtualEndOfSegment;
  pssSegments[0].RawLength = nPrevFileEndOfSegment;
  pssSegments[0].VirtualAddress = 0;
- pssSegments[0].Characteristics = 0;
+ pssSegments[0].Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA;
+ pssSegments[0].WriteCopy = TRUE;
 
  /* skip the headers segment */
  ++ pssSegments;
@@ -721,6 +696,7 @@
 
   /* see table above */
   pssSegments[i].Protection = SectionCharacteristicsToProtect[nCharacteristics >> 28];
+  pssSegments[i].WriteCopy = !(nCharacteristics & IMAGE_SCN_MEM_SHARED);
 
   if(pishSectionHeaders[i].Misc.VirtualSize == 0 || pishSectionHeaders[i].Misc.VirtualSize < pishSectionHeaders[i].SizeOfRawData)
    pssSegments[i].Length = pishSectionHeaders[i].SizeOfRawData;
@@ -730,12 +706,11 @@
   if(!AlignUp(&pssSegments[i].Length, pssSegments[i].Length, nSectionAlignment))
    DIE(("Cannot align the virtual size of section %u\n", i));
 
+  ASSERT(IsAligned(pssSegments[i].Length, nSectionAlignment));
+
   if(pssSegments[i].Length == 0)
    DIE(("Virtual size of section %u is null\n", i));
 
-  /* ExInitializeFastMutex(&pssSegments[i].Lock); */
-  /* pssSegments[i].ReferenceCount = 1; */
-  /* RtlZeroMemory(&pssSegments[i].PageDirectory, sizeof(pssSegments[i].PageDirectory)); */
   pssSegments[i].VirtualAddress = pishSectionHeaders[i].VirtualAddress;
   pssSegments[i].Characteristics = pishSectionHeaders[i].Characteristics;
 
@@ -749,17 +724,10 @@
   /* ensure the memory image is no larger than 4GB */
   if(!Intsafe_AddULong32(&nPrevVirtualEndOfSegment, pssSegments[i].VirtualAddress, pssSegments[i].Length))
    DIE(("The image is larger than 4GB\n"));
-
-  DPRINT("FileOffset    [%u] = %lX\n", i, (ULONG)pssSegments[i].FileOffset);
-  DPRINT("RawLength     [%u] = %lX\n", i, pssSegments[i].RawLength);
-  DPRINT("VirtualAddress[%u] = %lX\n", i, pssSegments[i].VirtualAddress);
-  DPRINT("Length        [%u] = %lX\n", i, pssSegments[i].Length);
  }
 
  /* spare our caller some work in validating the segments */
- *Flags |=
-  EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED |
-  EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP;
+ *Flags = EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED | EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP;
 
  if(nSectionAlignment >= PAGE_SIZE)
   *Flags |= EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED;

reactos/ntoskrnl/mm
section.c 1.166.2.4 -> 1.166.2.5
diff -u -r1.166.2.4 -r1.166.2.5
--- section.c	18 Dec 2004 02:36:09 -0000	1.166.2.4
+++ section.c	30 Dec 2004 01:59:59 -0000	1.166.2.5
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: section.c,v 1.166.2.4 2004/12/18 02:36:09 hyperion Exp $
+/* $Id: section.c,v 1.166.2.5 2004/12/30 01:59:59 hyperion Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/mm/section.c
@@ -29,7 +29,6 @@
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
-
 #define NDEBUG
 #include <internal/debug.h>
 
@@ -119,106 +118,6 @@
    return KeWaitForSingleObject(&File->Lock, 0, KernelMode, FALSE, NULL);
 }
 
-static VOID
-MmspReleaseFileLock(PFILE_OBJECT File)
-{
-   KeSetEvent(&File->Lock, IO_NO_INCREMENT, FALSE);
-}
-
-/* TODO: use this instead of ZwReadFile for all of our paging needs */
-static
-NTSTATUS
-NTAPI
-MmspPageRead(IN PFILE_OBJECT FileObject,
-             OUT PVOID Buffer,
-             IN ULONG BufferSize,
-             IN PLARGE_INTEGER Offset,
-             OUT PULONG ReadSize)
-{
-   NTSTATUS Status;
-   KEVENT Event;
-   PMDL Mdl;
-   IO_STATUS_BLOCK Iosb;
-
-   Mdl = IoAllocateMdl(Buffer, BufferSize, FALSE, FALSE, NULL);
-
-   if(Mdl == NULL)
-      return STATUS_INSUFFICIENT_RESOURCES;
-
-   MmBuildMdlForNonPagedPool(Mdl);
-   KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-   Status = IoPageRead(FileObject,
-                       Mdl,
-                       Offset,
-                       &Event,
-                       &Iosb);
-
-   if (Status == STATUS_PENDING)
-      KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
-
-   *ReadSize = Iosb.Information;
-   return Iosb.Status;
-}
-
-extern
-NTSTATUS
-NTAPI
-IopReadFile(IN PFILE_OBJECT FileObject,
-            IN KPROCESSOR_MODE AccessMode,
-	    IN PKEVENT EventObject OPTIONAL,
-	    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
-	    IN PVOID ApcContext OPTIONAL,
-	    OUT PIO_STATUS_BLOCK IoStatusBlock,
-	    OUT PVOID Buffer,
-	    IN ULONG Length,
-	    IN PLARGE_INTEGER ByteOffset OPTIONAL,
-	    IN PULONG Key OPTIONAL);
-
-/*
- * This is, basically, a hack. We "touch" the file with an 1-byte read so
- * caching is enabled for the file. This is wrong, wrong, WRONG: it moves the
- * file pointer (and I'm NOT hiding the bug by moving it back), it's subject to
- * whatever mode the file was opened in (synchronous vs asynchronous, cached vs
- * non-cached, etc.) and in real Windows this is never necessary, but we get
- * caching and memory mapping TOTALLY WRONG and BACKWARDS, with Mm calling Cc
- * instead of the other way around. But it isn't "more wrong" than the previous
- * implementation, so I'm leaving it this way. You're in for one hell of a ride,
- * should this break something and should you need to fix it...
- *   [KJK::Hyperion - 2004-12-17]
- */
-static
-NTSTATUS
-NTAPI
-MmspInitializeFileCache(IN PFILE_OBJECT FileObject)
-{
-   /*
-    * FIXME HACK HACK HORRIBLE HACK PLEASE LET ME DIE:
-    * Since the function can return too soon in case the file was opened for
-    * asyncronous I/O (this is the same behavior as before, when ZwReadFile was
-    * used), we at least limit the damage and pass static buffers. PLEASE, if
-    * you come across this comment, FIX THIS, because it means I still haven't.
-    * IopReadFile itself is a HACK, in kernel mode we should use completion
-    * routines, because any other notification mechanism is tailored towards
-    * consumption from user mode (e.g. EventObject can't be a bare KEVENT)
-    */
-   static UCHAR Buffer[1];
-   static IO_STATUS_BLOCK Iosb;
-   static LARGE_INTEGER FileOffset;
-
-   FileOffset.QuadPart = 0;
-
-   return IopReadFile(FileObject,
-                      KernelMode,
-                      NULL,
-                      NULL,
-                      NULL,
-                      &Iosb,
-                      Buffer,
-                      1,
-                      &FileOffset,
-                      NULL);
-}
 
 VOID
 MmFreePageTablesSectionSegment(PMM_SECTION_SEGMENT Segment)
@@ -239,14 +138,14 @@
 VOID
 MmFreeSectionSegments(PFILE_OBJECT FileObject)
 {
-   if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);if (FileObject->SectionObjectPointer->ImageSectionObject != NULL)
+   if (FileObject->SectionObjectPointer->ImageSectionObject != NULL)
    {
       PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
       PMM_SECTION_SEGMENT SectionSegments;
       ULONG NrSegments;
       ULONG i;
 
-      if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);ImageSectionObject = (PMM_IMAGE_SECTION_OBJECT)FileObject->SectionObjectPointer->ImageSectionObject;
+      ImageSectionObject = (PMM_IMAGE_SECTION_OBJECT)FileObject->SectionObjectPointer->ImageSectionObject;
       NrSegments = ImageSectionObject->NrSegments;
       SectionSegments = ImageSectionObject->Segments;
       for (i = 0; i < NrSegments; i++)
@@ -261,13 +160,13 @@
       }
       ExFreePool(ImageSectionObject->Segments);
       ExFreePool(ImageSectionObject);
-      if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);FileObject->SectionObjectPointer->ImageSectionObject = NULL;
+      FileObject->SectionObjectPointer->ImageSectionObject = NULL;
    }
-   if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);if (FileObject->SectionObjectPointer->DataSectionObject != NULL)
+   if (FileObject->SectionObjectPointer->DataSectionObject != NULL)
    {
       PMM_SECTION_SEGMENT Segment;
 
-      if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);Segment = (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer->
+      Segment = (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer->
                 DataSectionObject;
 
       if (Segment->ReferenceCount != 0)
@@ -277,7 +176,7 @@
       }
       MmFreePageTablesSectionSegment(Segment);
       ExFreePool(Segment);
-      if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);FileObject->SectionObjectPointer->DataSectionObject = NULL;
+      FileObject->SectionObjectPointer->DataSectionObject = NULL;
    }
 }
 
@@ -437,7 +336,7 @@
                (Offset + PAGE_SIZE <= Segment->RawLength || !IsImageSection))
          {
             NTSTATUS Status;
-            if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
+            Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
             IsDirectMapped = TRUE;
             Status = CcRosUnmapCacheSegment(Bcb, FileOffset, Dirty);
             if (!NT_SUCCESS(Status))
@@ -557,7 +456,7 @@
    ULONG Length;
 
    FileObject = MemoryArea->Data.SectionData.Section->FileObject;
-   if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
+   Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
    RawLength = MemoryArea->Data.SectionData.Segment->RawLength;
    FileOffset = SegOffset + MemoryArea->Data.SectionData.Segment->FileOffset;
    IsImageSection = MemoryArea->Data.SectionData.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
@@ -752,7 +651,7 @@
    /*
     * Check if this page needs to be mapped COW
     */
-   if ((Segment->Protection & PAGE_IS_WRITECOPY || MemoryArea->Data.SectionData.WriteCopyView) &&
+   if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
        (Region->Protect == PAGE_READWRITE ||
        Region->Protect == PAGE_EXECUTE_READWRITE))
    {
@@ -1270,7 +1169,7 @@
    /*
     * Check if we are doing COW
     */
-   if (!((Segment->Protection & PAGE_IS_WRITECOPY || MemoryArea->Data.SectionData.WriteCopyView) &&
+   if (!((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
          (Region->Protect == PAGE_READWRITE ||
           Region->Protect == PAGE_EXECUTE_READWRITE)))
    {
@@ -1462,7 +1361,7 @@
    if (FileObject != NULL &&
        !(Context.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED))
    {
-      if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
+      Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
 
       /*
        * If the file system is letting us go directly to the cache and the
@@ -1806,7 +1705,7 @@
    if (FileObject != NULL &&
          !(Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED))
    {
-      if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
+      Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
 
       /*
        * If the file system is letting us go directly to the cache and the
@@ -1933,7 +1832,7 @@
    MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, BaseAddress);
    Segment = MemoryArea->Data.SectionData.Segment;
 
-   if ((Segment->Protection & PAGE_IS_WRITECOPY || MemoryArea->Data.SectionData.WriteCopyView) &&
+   if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
          (NewProtect == PAGE_READWRITE || NewProtect == PAGE_EXECUTE_READWRITE))
    {
       DoCOW = TRUE;
@@ -2122,26 +2021,22 @@
          return;
 
       SectionSegments = Section->ImageSection->Segments;
-      
-      if (SectionSegments)
+      NrSegments = Section->ImageSection->NrSegments;
+
+      for (i = 0; i < NrSegments; i++)
       {
-         NrSegments = Section->ImageSection->NrSegments;
-   
-         for (i = 0; i < NrSegments; i++)
+         if (SectionSegments[i].Characteristics & IMAGE_SECTION_CHAR_SHARED)
          {
-            if (SectionSegments[i].Characteristics & IMAGE_SECTION_CHAR_SHARED)
+            MmLockSectionSegment(&SectionSegments[i]);
+         }
+         RefCount = InterlockedDecrementUL(&SectionSegments[i].ReferenceCount);
+         if (SectionSegments[i].Characteristics & IMAGE_SECTION_CHAR_SHARED)
+         {
+            if (RefCount == 0)
             {
-               MmLockSectionSegment(&SectionSegments[i]);
-            }
-            RefCount = InterlockedDecrement(&SectionSegments[i].ReferenceCount);
-            if (SectionSegments[i].Characteristics & IMAGE_SECTION_CHAR_SHARED)
-            {
-               if (RefCount == 0)
-               {
-                  MmpFreePageFileSegment(&SectionSegments[i]);
-               }
-               MmUnlockSectionSegment(&SectionSegments[i]);
+               MmpFreePageFileSegment(&SectionSegments[i]);
             }
+            MmUnlockSectionSegment(&SectionSegments[i]);
          }
       }
    }
@@ -2163,7 +2058,7 @@
       }
       else
       {
-         InterlockedDecrement(&Section->Segment->ReferenceCount);
+         InterlockedDecrementUL(&Section->Segment->ReferenceCount);
       }
    }
    if (Section->FileObject != NULL)
@@ -2339,6 +2234,7 @@
    Segment->RawLength = MaximumSize.u.LowPart;
    Segment->Length = PAGE_ROUND_UP(MaximumSize.u.LowPart);
    Segment->Flags = MM_PAGEFILE_SEGMENT;
+   Segment->WriteCopy = FALSE;
    RtlZeroMemory(&Segment->PageDirectory, sizeof(SECTION_PAGE_DIRECTORY));
    Segment->VirtualAddress = 0;
    Segment->Characteristics = 0;
@@ -2477,7 +2373,7 @@
       }
    }
 
-   if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);if (FileObject->SectionObjectPointer == NULL ||
+   if (FileObject->SectionObjectPointer == NULL ||
          FileObject->SectionObjectPointer->SharedCacheMap == NULL)
    {
       /*
@@ -2501,7 +2397,7 @@
          ObDereferenceObject(FileObject);
          return(Status);
       }
-      if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);if (FileObject->SectionObjectPointer == NULL ||
+      if (FileObject->SectionObjectPointer == NULL ||
             FileObject->SectionObjectPointer->SharedCacheMap == NULL)
       {
          /* FIXME: handle this situation */
@@ -2526,13 +2422,13 @@
     * If this file hasn't been mapped as a data file before then allocate a
     * section segment to describe the data file mapping
     */
-   if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);if (FileObject->SectionObjectPointer->DataSectionObject == NULL)
+   if (FileObject->SectionObjectPointer->DataSectionObject == NULL)
    {
       Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT),
                                       TAG_MM_SECTION_SEGMENT);
       if (Segment == NULL)
       {
-         MmspReleaseFileLock(FileObject);
+         KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
          ObDereferenceObject(Section);
          ObDereferenceObject(FileObject);
          return(STATUS_NO_MEMORY);
@@ -2544,12 +2440,13 @@
        * Set the lock before assigning the segment to the file object
        */
       ExAcquireFastMutex(&Segment->Lock);
-      if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);FileObject->SectionObjectPointer->DataSectionObject = (PVOID)Segment;
+      FileObject->SectionObjectPointer->DataSectionObject = (PVOID)Segment;
 
       Segment->FileOffset = 0;
       Segment->Protection = SectionPageProtection;
       Segment->Flags = MM_DATAFILE_SEGMENT;
       Segment->Characteristics = 0;
+      Segment->WriteCopy = FALSE;
       if (AllocationAttributes & SEC_RESERVE)
       {
          Segment->Length = Segment->RawLength = 0;
@@ -2568,11 +2465,11 @@
        * If the file is already mapped as a data file then we may need
        * to extend it
        */
-      if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);Segment =
+      Segment =
          (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer->
          DataSectionObject;
       Section->Segment = Segment;
-      InterlockedIncrement(&Segment->ReferenceCount);
+      InterlockedIncrementUL(&Segment->ReferenceCount);
       MmLockSectionSegment(Segment);
 
       if (MaximumSize.u.LowPart > Segment->RawLength &&
@@ -2586,7 +2483,7 @@
    Section->FileObject = FileObject;
    Section->MaximumSize = MaximumSize;
    CcRosReferenceCache(FileObject);
-   MmspReleaseFileLock(FileObject);
+   KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
    *SectionObject = Section;
    return(STATUS_SUCCESS);
 }
@@ -2599,7 +2496,18 @@
 (
  IN CONST VOID * FileHeader,
  IN SIZE_T FileHeaderSize,
- IN PFILE_OBJECT File,
+ IN PVOID File,
+ OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
+ OUT PULONG Flags,
+ IN PEXEFMT_CB_READ_FILE ReadFileCb,
+ IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
+);
+
+extern NTSTATUS NTAPI ElfFmtCreateSection
+(
+ IN CONST VOID * FileHeader,
+ IN SIZE_T FileHeaderSize,
+ IN PVOID File,
  OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
  OUT PULONG Flags,
  IN PEXEFMT_CB_READ_FILE ReadFileCb,
@@ -2613,7 +2521,8 @@
 
 static PEXEFMT_LOADER ExeFmtpLoaders[] =
 {
- PeFmtCreateSection
+ PeFmtCreateSection,
+ ElfFmtCreateSection
 };
 
 static
@@ -2640,7 +2549,7 @@
 static
 NTSTATUS
 NTAPI
-ExeFmtpReadFile(IN PFILE_OBJECT FileObject,
+ExeFmtpReadFile(IN PVOID File,
                 IN PLARGE_INTEGER Offset,
                 IN ULONG Length,
                 OUT PVOID * Data,
@@ -2690,13 +2599,40 @@
 
    UsedSize = 0;
 
-   Status = MmspPageRead(FileObject,
+#if 0
+   Status = MmspPageRead(File,
                          Buffer,
                          BufferSize,
                          &FileOffset,
                          &UsedSize);
+#else
+/*
+ * FIXME: if we don't use ZwReadFile, caching is not enabled for the file and
+ * nothing will work. But using ZwReadFile is wrong, and using its side effects
+ * to initialize internal state is even worse. Our cache manager is in need of
+ * professional help
+ */
+   {
+      IO_STATUS_BLOCK Iosb;
 
-   if(UsedSize < OffsetAdjustment)
+      Status = ZwReadFile(File,
+                          NULL,
+                          NULL,
+                          NULL,
+                          &Iosb,
+                          Buffer,
+                          BufferSize,
+                          &FileOffset,
+                          NULL);
+   
+      if(NT_SUCCESS(Status))
+      {
+         UsedSize = Iosb.Information;
+      }
+   }
+#endif
+
+   if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
    {
       Status = STATUS_IN_PAGE_ERROR;
       ASSERT(!NT_SUCCESS(Status));
@@ -3050,24 +2986,207 @@
 }
 
 NTSTATUS
+ExeFmtpCreateImageSection(HANDLE FileHandle,
+                          PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
+{
+   LARGE_INTEGER Offset;
+   PVOID FileHeader;
+   PVOID FileHeaderBuffer;
+   ULONG FileHeaderSize;
+   ULONG Flags;
+   ULONG OldNrSegments;
+   NTSTATUS Status;
+   ULONG i;
+
+   /*
+    * Read the beginning of the file (2 pages). Should be enough to contain
+    * all (or most) of the headers
+    */
+   Offset.QuadPart = 0;
+
+   /* FIXME: use FileObject instead of FileHandle */
+   Status = ExeFmtpReadFile (FileHandle,
+                             &Offset,
+                             PAGE_SIZE * 2,
+                             &FileHeader,
+                             &FileHeaderBuffer,
+                             &FileHeaderSize);
+
+   if (!NT_SUCCESS(Status))
+      return Status;
+
+   if (FileHeaderSize == 0)
+   {
+      ExFreePool(FileHeaderBuffer);
+      return STATUS_UNSUCCESSFUL;
+   }
+
+   /*
+    * Look for a loader that can handle this executable
+    */
+   for (i = 0; i < RTL_NUMBER_OF(ExeFmtpLoaders); ++ i)
+   {
+      RtlZeroMemory(ImageSectionObject, sizeof(*ImageSectionObject));
+      Flags = 0;
+
+      /* FIXME: use FileObject instead of FileHandle */
+      Status = ExeFmtpLoaders[i](FileHeader,
+                                 FileHeaderSize,
+                                 FileHandle,
+                                 ImageSectionObject,
+                                 &Flags,
+                                 ExeFmtpReadFile,
+                                 ExeFmtpAllocateSegments);
+
+      if (!NT_SUCCESS(Status))
+      {
+         if (ImageSectionObject->Segments)
+         {
+            ExFreePool(ImageSectionObject->Segments);
+            ImageSectionObject->Segments = NULL;
+         }
+      }
+
+      if (Status != STATUS_ROS_EXEFMT_UNKNOWN_FORMAT)
+         break;
+   }
+
+   ExFreePool(FileHeaderBuffer);
+
+   /*
+    * No loader handled the format
+    */
+   if (Status == STATUS_ROS_EXEFMT_UNKNOWN_FORMAT)
+   {
+      Status = STATUS_INVALID_IMAGE_FORMAT;
+      ASSERT(!NT_SUCCESS(Status));
+   }
+
+   if (!NT_SUCCESS(Status))
+      return Status;
+
+   ASSERT(ImageSectionObject->Segments != NULL);
+
+   /*
+    * Some defaults
+    */
+   /* FIXME? are these values platform-dependent? */
+   if(ImageSectionObject->StackReserve == 0)
+      ImageSectionObject->StackReserve = 0x40000;
+  
+   if(ImageSectionObject->StackCommit == 0)
+      ImageSectionObject->StackCommit = 0x1000;
+  
+   if(ImageSectionObject->ImageBase == 0)
+   {
+      if(ImageSectionObject->ImageCharacteristics & IMAGE_FILE_DLL)
+         ImageSectionObject->ImageBase = 0x10000000;
+      else
+         ImageSectionObject->ImageBase = 0x00400000;
+   }
+
+   /*
+    * And now the fun part: fixing the segments
+    */
+
+   /* Sort them by virtual address */
+   MmspSortSegments(ImageSectionObject, Flags);
+
+   /* Ensure they don't overlap in memory */
+   if (!MmspCheckSegmentBounds(ImageSectionObject, Flags))
+      return STATUS_INVALID_IMAGE_FORMAT;
+
+   /* Ensure they are aligned */
+   OldNrSegments = ImageSectionObject->NrSegments;
+
+   if (!MmspPageAlignSegments(ImageSectionObject, Flags))
+      return STATUS_INVALID_IMAGE_FORMAT;
+
+   /* Trim them if the alignment phase merged some of them */
+   if (ImageSectionObject->NrSegments < OldNrSegments)
+   {
+      PMM_SECTION_SEGMENT Segments;
+      SIZE_T SizeOfSegments;
+
+      SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * ImageSectionObject->NrSegments;
+
+      Segments = ExAllocatePoolWithTag(NonPagedPool,
+                                       SizeOfSegments,
+                                       TAG_MM_SECTION_SEGMENT);
+
+      if (Segments == NULL)
+         return STATUS_INSUFFICIENT_RESOURCES;
+
+      RtlCopyMemory(Segments, ImageSectionObject->Segments, SizeOfSegments);
+      ExFreePool(ImageSectionObject->Segments);
+      ImageSectionObject->Segments = Segments;
+   }
+
+   /* And finish their initialization */
+   for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
+   {
+      ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock);
+      ImageSectionObject->Segments[i].ReferenceCount = 1;
+
+      RtlZeroMemory(&ImageSectionObject->Segments[i].PageDirectory,
+                    sizeof(ImageSectionObject->Segments[i].PageDirectory));
+   }
+
+   ASSERT(NT_SUCCESS(Status));
+   return Status;
+}
+
+NTSTATUS
 MmCreateImageSection(PSECTION_OBJECT *SectionObject,
                      ACCESS_MASK DesiredAccess,
                      POBJECT_ATTRIBUTES ObjectAttributes,
                      PLARGE_INTEGER UMaximumSize,
                      ULONG SectionPageProtection,
                      ULONG AllocationAttributes,
-                     PFILE_OBJECT FileObject)
+                     HANDLE FileHandle)
 {
-   NTSTATUS Status;
    PSECTION_OBJECT Section;
+   NTSTATUS Status;
+   PFILE_OBJECT FileObject;
+   PMM_SECTION_SEGMENT SectionSegments;
    PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
    ULONG i;
+   ULONG FileAccess = 0;
 
    /*
     * Specifying a maximum size is meaningless for an image section
     */
    if (UMaximumSize != NULL)
+   {
       return(STATUS_INVALID_PARAMETER_4);
+   }
+
+   /*
+    * Check file access required
+    */
+   if (SectionPageProtection & PAGE_READWRITE ||
+         SectionPageProtection & PAGE_EXECUTE_READWRITE)
+   {
+      FileAccess = FILE_READ_DATA | FILE_WRITE_DATA;
+   }
+   else
+   {
+      FileAccess = FILE_READ_DATA;
+   }
+
+   /*
+    * Reference the file handle
+    */
+   Status = ObReferenceObjectByHandle(FileHandle,
+                                      FileAccess,
+                                      IoFileObjectType,
+                                      UserMode,
+                                      (PVOID*)(PVOID)&FileObject,
+                                      NULL);
+   if (!NT_SUCCESS(Status))
+   {
+      return Status;
+   }
 
    /*
     * Create the section
@@ -3080,17 +3199,18 @@
                             sizeof(SECTION_OBJECT),
                             0,
                             0,
-                            (PVOID*)&Section);
-
+                            (PVOID*)(PVOID)&Section);
    if (!NT_SUCCESS(Status))
-      return Status;
+   {
+      ObDereferenceObject(FileObject);
+      return(Status);
+   }
 
    /*
     * Initialize it
     */
    Section->SectionPageProtection = SectionPageProtection;
    Section->AllocationAttributes = AllocationAttributes;
-   Section->ImageSection = NULL;
    InitializeListHead(&Section->ViewListHead);
    KeInitializeSpinLock(&Section->ViewListLock);
 
@@ -3100,214 +3220,66 @@
     */
    Status = CcTryToInitializeFileCache(FileObject);
 
-   if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);if (!NT_SUCCESS(Status) || FileObject->SectionObjectPointer->ImageSectionObject == NULL)
+   if (!NT_SUCCESS(Status) || FileObject->SectionObjectPointer->ImageSectionObject == NULL)
    {
-      LARGE_INTEGER Offset;
-      PVOID FileHeader;
-      ULONG FileHeaderSize;
-      ULONG Flags;
-      ULONG OldNrSegments;
       NTSTATUS StatusExeFmt;
 
-      Status = MmspInitializeFileCache(FileObject);
-
-      if (!NT_SUCCESS(Status))
+      ImageSectionObject = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_IMAGE_SECTION_OBJECT), TAG_MM_SECTION_SEGMENT);
+      if (ImageSectionObject == NULL)
       {
-         goto l_DereferenceSection;
+         ObDereferenceObject(FileObject);
+         ObDereferenceObject(Section);
+         return(STATUS_NO_MEMORY);
       }
 
-      /*
-       * Allocate the image section object
-       */
-      ImageSectionObject = ExAllocatePoolWithTag (NonPagedPool,
-                                                  sizeof(MM_IMAGE_SECTION_OBJECT),
-                                                  TAG_MM_SECTION_SEGMENT);
+      StatusExeFmt = ExeFmtpCreateImageSection(FileHandle, ImageSectionObject);
 
-      if (ImageSectionObject == NULL)
+      if (!NT_SUCCESS(StatusExeFmt))
       {
-         Status = STATUS_INSUFFICIENT_RESOURCES;
-         goto l_DereferenceSection;
+         if(ImageSectionObject->Segments != NULL)
+            ExFreePool(ImageSectionObject->Segments);
+
+         ExFreePool(ImageSectionObject);
+         ObDereferenceObject(Section);
+         ObDereferenceObject(FileObject);
+         return(StatusExeFmt);
       }
 
       Section->ImageSection = ImageSectionObject;
+      ASSERT(ImageSectionObject->Segments);
 
       /*
        * Lock the file
        */
       Status = MmspWaitForFileLock(FileObject);
-
-      if (!NT_SUCCESS(Status))
-         goto l_FreeImageSection;
-
-      /*
-       * Read the beginning of the file (2 pages). Should be enough to contain
-       * all (or most) of the headers
-       */
-      FileHeaderSize = PAGE_SIZE * 2;
-      FileHeader = ExAllocatePool(NonPagedPool, FileHeaderSize);
-
-      if (FileHeader == NULL)
-      {
-         Status = STATUS_INSUFFICIENT_RESOURCES;
-         goto l_UnlockFile;
-      }
-
-      Offset.QuadPart = 0;
-      Status = MmspPageRead (FileObject,
-                             FileHeader,
-                             FileHeaderSize,
-                             &Offset,
-                             &FileHeaderSize);
-
-      if (!NT_SUCCESS(Status))
-         goto l_UnlockFile;
-
-      if (FileHeaderSize == 0)
-      {
-         Status = STATUS_UNSUCCESSFUL;
-         goto l_UnlockFile;
-      }
-
-      Flags = 0;
-
-      /*
-       * Look for a loader that can handle this executable
-       */
-      for (i = 0; i < RTL_NUMBER_OF(ExeFmtpLoaders); ++ i)
-      {
-         ImageSectionObject->Segments = NULL;
-
-         StatusExeFmt = ExeFmtpLoaders[i](FileHeader,
-                                          FileHeaderSize,
-                                          FileObject,
-                                          ImageSectionObject,
-                                          &Flags,
-                                          ExeFmtpReadFile,
-                                          ExeFmtpAllocateSegments);
-
-         if (!NT_SUCCESS(StatusExeFmt))
-         {
-            if (ImageSectionObject->Segments)
-            {
-               ExFreePool(ImageSectionObject->Segments);
-               ImageSectionObject->Segments = NULL;
-            }
-         }
-
-         if (StatusExeFmt != STATUS_ROS_EXEFMT_UNKNOWN_FORMAT)
-            break;
-      }
-
-      /*
-       * No loader handled the format
-       */
-      if (StatusExeFmt == STATUS_ROS_EXEFMT_UNKNOWN_FORMAT)
-      {
-         Status = STATUS_INVALID_IMAGE_FORMAT;
-         ASSERT(!NT_SUCCESS(Status));
-      }
-      else
-      {
-         Status = StatusExeFmt;
-      }
-
-      ExFreePool(FileHeader);
-
       if (!NT_SUCCESS(Status))
       {
-         goto l_UnlockFile;
-      }
-
-      /*
-       * And now the fun part: fixing the segments
-       */
-
-      /* Sort them by virtual address */
-      MmspSortSegments(ImageSectionObject, Flags);
-
-      Status = STATUS_INVALID_IMAGE_FORMAT;
-
-      /* Ensure they don't overlap in memory */
-      if (!MmspCheckSegmentBounds(ImageSectionObject, Flags))
-      {
-         goto l_UnlockFile;
-      }
-
-      /* Ensure they are aligned */
-      OldNrSegments = ImageSectionObject->NrSegments;
-
-      if (!MmspPageAlignSegments(ImageSectionObject, Flags))
-      {
-         goto l_UnlockFile;
-      }
-
-      /* Trim them if the alignment phase merged some of them */
-      if (ImageSectionObject->NrSegments < OldNrSegments)
-      {
-         PMM_SECTION_SEGMENT Segments;
-         SIZE_T SizeOfSegments;
-
-         SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * ImageSectionObject->NrSegments;
-
-         Status = STATUS_INSUFFICIENT_RESOURCES;
-
-         Segments = ExAllocatePoolWithTag(NonPagedPool,
-                                          SizeOfSegments,
-                                          TAG_MM_SECTION_SEGMENT);
-
-         if (Segments == NULL)
-            goto l_UnlockFile;
-
-         RtlCopyMemory(Segments, ImageSectionObject->Segments, SizeOfSegments);
          ExFreePool(ImageSectionObject->Segments);
-         ImageSectionObject->Segments = Segments;
-      }
-
-      /* And finish their initialization */
-      for ( i = 0; i < ImageSectionObject->NrSegments; ++ i )
-      {
-         ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock);
-         ImageSectionObject->Segments[i].ReferenceCount = 1;
+         ExFreePool(ImageSectionObject);
+         ObDereferenceObject(Section);
+         ObDereferenceObject(FileObject);
+         return(Status);
       }
 
-      if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);if (0 != InterlockedCompareExchange((PLONG)&FileObject->SectionObjectPointer->ImageSectionObject,
-                                          (LONG)ImageSectionObject, 0))
+      if (0 != InterlockedCompareExchangeUL(&FileObject->SectionObjectPointer->ImageSectionObject,
+                                            ImageSectionObject, 0))
       {
          /*
           * An other thread has initialized the some image in the background
           */
          ExFreePool(ImageSectionObject->Segments);
          ExFreePool(ImageSectionObject);
-         if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
+         ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
          Section->ImageSection = ImageSectionObject;
+         SectionSegments = ImageSectionObject->Segments;
 
          for (i = 0; i < ImageSectionObject->NrSegments; i++)
          {
-            InterlockedIncrement(&ImageSectionObject->Segments[i].ReferenceCount);
+            InterlockedIncrementUL(&SectionSegments[i].ReferenceCount);
          }
       }
 
-      ASSERT(NT_SUCCESS(StatusExeFmt));
       Status = StatusExeFmt;
-      goto l_Success;
-
-l_UnlockFile:
-      MmspReleaseFileLock(FileObject);
-
-l_FreeImageSection:
-      if (ImageSectionObject->Segments)
-         ExFreePool(ImageSectionObject->Segments);
-
-      ExFreePool(ImageSectionObject);
-      Section->ImageSection = NULL;
-
-l_DereferenceSection:
-      ObDereferenceObject(Section);
-
-      return Status;
-
-l_Success:
-      (void)0;
    }
    else
    {
@@ -3318,33 +3290,29 @@
       if (Status != STATUS_SUCCESS)
       {
          ObDereferenceObject(Section);
+         ObDereferenceObject(FileObject);
          return(Status);
       }
 
-      if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
+      ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject;
       Section->ImageSection = ImageSectionObject;
+      SectionSegments = ImageSectionObject->Segments;
 
       /*
-       * Just reference all the section segments
+       * Otherwise just reference all the section segments
        */
       for (i = 0; i < ImageSectionObject->NrSegments; i++)
       {
-         InterlockedIncrement(&ImageSectionObject->Segments[i].ReferenceCount);
+         InterlockedIncrementUL(&SectionSegments[i].ReferenceCount);
       }
 
       Status = STATUS_SUCCESS;
    }
-
    Section->FileObject = FileObject;
    CcRosReferenceCache(FileObject);
-   MmspReleaseFileLock(FileObject);
+   KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
    *SectionObject = Section;
-
-   /*
-    * It's important that Status, and not STATUS_SUCCESS, is returned, because
-    * Status may be one of the STATUS_ROS_EXEFMT_LOADED_FORMAT constants
-    */
-   return Status;
+   return(Status);
 }
 
 /*
@@ -3462,8 +3430,8 @@
                                BoundaryAddressMultiple);
    if (!NT_SUCCESS(Status))
    {
-      DPRINT1("Mapping between 0x%.8X and 0x%.8X failed.\n",
-              (*BaseAddress), (char*)(*BaseAddress) + ViewSize);
+      DPRINT1("Mapping between 0x%.8X and 0x%.8X failed (%X).\n",
+              (*BaseAddress), (char*)(*BaseAddress) + ViewSize, Status);
       return(Status);
    }
 
@@ -3652,7 +3620,7 @@
       if (Page == PFN_FROM_SSE(Entry) && Dirty)
       {
          FileObject = MemoryArea->Data.SectionData.Section->FileObject;
-         if(FileObject->SectionObjectPointer == (PVOID)0xCCCCCCCC) KEBUGCHECK(0);Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
+         Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
          CcRosMarkDirtyCacheSegment(Bcb, Offset);
          ASSERT(SwapEntry == 0);
       }
@@ -3812,7 +3780,7 @@
          {
             if (Segment == &SectionSegments[i])
             {
-               ImageBaseAddress = (char*)BaseAddress - SectionSegments[i].VirtualAddress;
+               ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].VirtualAddress;
                break;
             }
          }
@@ -3827,7 +3795,7 @@
          if (!(SectionSegments[i].Characteristics & IMAGE_SECTION_NOLOAD))
          {
             PVOID SBaseAddress = (PVOID)
-                                 ((char*)ImageBaseAddress + SectionSegments[i].VirtualAddress);
+                                 ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].VirtualAddress);
 
             Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
          }
@@ -4262,7 +4230,7 @@
          if (!(SectionSegments[i].Characteristics & IMAGE_SECTION_NOLOAD))
          {
             PVOID SBaseAddress = (PVOID)
-                                 ((char*)ImageBase + SectionSegments[i].VirtualAddress);
[truncated at 1000 lines; 107 more skipped]

reactos/ntoskrnl/mm/i386
page.c 1.77.2.4 -> 1.77.2.5
diff -u -r1.77.2.4 -r1.77.2.5
--- page.c	18 Dec 2004 02:36:08 -0000	1.77.2.4
+++ page.c	30 Dec 2004 01:59:59 -0000	1.77.2.5
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: page.c,v 1.77.2.4 2004/12/18 02:36:08 hyperion Exp $
+/* $Id: page.c,v 1.77.2.5 2004/12/30 01:59:59 hyperion Exp $
  *
  * PROJECT:     ReactOS kernel
  * FILE:        ntoskrnl/mm/i386/page.c
@@ -426,7 +426,7 @@
    if (Ke386Pae)
    {
       ULONGLONG ZeroPde = 0LL;
-      ExfpInterlockedExchange64(PAE_ADDR_TO_PDE(Address), &ZeroPde);
+      ExfpInterlockedExchange64UL(PAE_ADDR_TO_PDE(Address), &ZeroPde);
    }
    else
    {
@@ -470,7 +470,7 @@
          }
       }
       Pfn = PAE_PTE_TO_PFN(*(PAE_ADDR_TO_PDE(Address)));
-      ExfpInterlockedExchange64(PAE_ADDR_TO_PDE(Address), &ZeroPte);
+      ExfpInterlockedExchange64UL(PAE_ADDR_TO_PDE(Address), &ZeroPte);
    }
    else
    {
@@ -536,7 +536,7 @@
          KEBUGCHECK(0);
       }
       PageDir += PAE_ADDR_TO_PDE_PAGE_OFFSET(Address);
-      Entry = ExfInterlockedCompareExchange64(PageDir, &ZeroEntry, &ZeroEntry);
+      Entry = ExfInterlockedCompareExchange64UL(PageDir, &ZeroEntry, &ZeroEntry);
       if (Entry == 0LL)
       {
          if (Create == FALSE)
@@ -550,7 +550,7 @@
 	    KEBUGCHECK(0);
 	 }
          Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER; 
-	 Entry = ExfInterlockedCompareExchange64(PageDir, &Entry, &ZeroEntry);
+	 Entry = ExfInterlockedCompareExchange64UL(PageDir, &Entry, &ZeroEntry);
 	 if (Entry != 0LL)
 	 {
 	    MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
@@ -570,7 +570,7 @@
       return Pt + PAE_ADDR_TO_PTE_OFFSET(Address);
    }
    PageDir = PAE_ADDR_TO_PDE(Address);
-   if (0LL == ExfInterlockedCompareExchange64(PageDir, &ZeroEntry, &ZeroEntry))
+   if (0LL == ExfInterlockedCompareExchange64UL(PageDir, &ZeroEntry, &ZeroEntry))
    {
       if (Address >= (PVOID)KERNEL_BASE)
       {
@@ -590,12 +590,12 @@
 	    {
 	       Entry |= PA_GLOBAL;
 	    }
-	    if (0LL != ExfInterlockedCompareExchange64(&MmGlobalKernelPageDirectoryForPAE[PAE_ADDR_TO_PDE_OFFSET(Address)], &Entry, &ZeroEntry))
+	    if (0LL != ExfInterlockedCompareExchange64UL(&MmGlobalKernelPageDirectoryForPAE[PAE_ADDR_TO_PDE_OFFSET(Address)], &Entry, &ZeroEntry))
 	    {
 	       MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
 	    }
 	 }
-	 ExfInterlockedCompareExchange64(PageDir, &MmGlobalKernelPageDirectoryForPAE[PAE_ADDR_TO_PDE_OFFSET(Address)], &ZeroEntry);
+	 ExfInterlockedCompareExchange64UL(PageDir, &MmGlobalKernelPageDirectoryForPAE[PAE_ADDR_TO_PDE_OFFSET(Address)], &ZeroEntry);
       }
       else
       {
@@ -609,7 +609,7 @@
 	    KEBUGCHECK(0);
 	 }
 	 Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER;
-         Entry = ExfInterlockedCompareExchange64(PageDir, &Entry, &ZeroEntry);
+         Entry = ExfInterlockedCompareExchange64UL(PageDir, &Entry, &ZeroEntry);
 	 if (Entry != 0LL)
 	 {
 	    MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
@@ -647,7 +647,7 @@
 	 {
 	    KEBUGCHECK(0);
 	 }
-         Entry = InterlockedCompareExchange(&PageDir[PdeOffset], PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0);
+         Entry = InterlockedCompareExchangeUL(&PageDir[PdeOffset], PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0);
 	 if (Entry != 0)
 	 {
 	    MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
@@ -687,7 +687,7 @@
 	    {
 	       Entry |= PA_GLOBAL;
 	    }
-	    if(0 != InterlockedCompareExchange(&MmGlobalKernelPageDirectory[PdeOffset], Entry, 0))
+	    if(0 != InterlockedCompareExchangeUL(&MmGlobalKernelPageDirectory[PdeOffset], Entry, 0))
 	    {
 	       MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
 	    }
@@ -705,7 +705,7 @@
 	 {
 	    KEBUGCHECK(0);
 	 }
-         Entry = InterlockedCompareExchange(PageDir, PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0);
+         Entry = InterlockedCompareExchangeUL(PageDir, PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0);
 	 if (Entry != 0)
 	 {
 	    MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
@@ -820,7 +820,7 @@
       {
         Pte = *Pt;
 	tmpPte = Pte & ~PA_PRESENT;
-      } while (Pte != ExfInterlockedCompareExchange64(Pt, &tmpPte, &Pte)); 
+      } while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte)); 
 
       MiFlushTlb((PULONG)Pt, Address);
       WasValid = PAE_PAGE_MASK(Pte) != 0LL ? TRUE : FALSE;
@@ -857,7 +857,7 @@
       do
       {
         Pte = *Pt;
-      } while (Pte != InterlockedCompareExchange(Pt, Pte & ~PA_PRESENT, Pte)); 
+      } while (Pte != InterlockedCompareExchangeUL(Pt, Pte & ~PA_PRESENT, Pte)); 
 
       MiFlushTlb(Pt, Address);
       WasValid = (PAGE_MASK(Pte) != 0);
@@ -893,7 +893,7 @@
          /*
           * Set the entry to zero
           */
-	 ExfpInterlockedExchange64(Pt, &ZeroPte);
+	 ExfpInterlockedExchange64UL(Pt, &ZeroPte);
          MiFlushTlb((PULONG)Pt, Address);
       }
    }
@@ -948,7 +948,7 @@
        * Atomically set the entry to zero and get the old value.
        */
       Pte = 0LL;
-      Pte = ExfpInterlockedExchange64(Pt, &Pte);
+      Pte = ExfpInterlockedExchange64UL(Pt, &Pte);
 
       MiFlushTlb((PULONG)Pt, Address);
 
@@ -1003,7 +1003,7 @@
       /*
        * Atomically set the entry to zero and get the old value.
        */
-      Pte = InterlockedExchange(Pt, 0);
+      Pte = InterlockedExchangeUL(Pt, 0);
 
       MiFlushTlb(Pt, Address);
 
@@ -1079,7 +1079,7 @@
        * Atomically set the entry to zero and get the old value.
        */
       Pte = 0LL;
-      Pte = ExfpInterlockedExchange64(Pt, &Pte);
+      Pte = ExfpInterlockedExchange64UL(Pt, &Pte);
 
       MiFlushTlb((PULONG)Pt, Address);
 
@@ -1123,7 +1123,7 @@
       /*
        * Atomically set the entry to zero and get the old value.
        */
-      Pte = InterlockedExchange(Pt, 0);
+      Pte = InterlockedExchangeUL(Pt, 0);
 
       MiFlushTlb(Pt, Address);
 
@@ -1230,7 +1230,7 @@
       {
          Pte = *Pt;
 	 tmpPte = Pte & ~PA_ACCESSED;
-      } while (Pte != ExfInterlockedCompareExchange64(Pt, &tmpPte, &Pte));
+      } while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
 
       if (Pte & PA_ACCESSED)
       {
@@ -1257,7 +1257,7 @@
       do
       {
          Pte = *Pt;
-      } while (Pte != InterlockedCompareExchange(Pt, Pte & ~PA_ACCESSED, Pte));
+      } while (Pte != InterlockedCompareExchangeUL(Pt, Pte & ~PA_ACCESSED, Pte));
 
       if (Pte & PA_ACCESSED)
       {
@@ -1296,7 +1296,7 @@
       {
          Pte = *Pt;
 	 tmpPte = Pte & ~PA_DIRTY;
-      } while (Pte != ExfInterlockedCompareExchange64(Pt, &tmpPte, &Pte));
+      } while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
 
       if (Pte & PA_DIRTY)
       {
@@ -1322,7 +1322,7 @@
       do
       {
          Pte = *Pt;
-      } while (Pte != InterlockedCompareExchange(Pt, Pte & ~PA_DIRTY, Pte));
+      } while (Pte != InterlockedCompareExchangeUL(Pt, Pte & ~PA_DIRTY, Pte));
 
       if (Pte & PA_DIRTY)
       {
@@ -1358,7 +1358,7 @@
       {
          Pte = *Pt;
 	 tmpPte = Pte | PA_DIRTY; 
-      } while (Pte != ExfInterlockedCompareExchange64(Pt, &tmpPte, &Pte));
+      } while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
       if (!(Pte & PA_DIRTY))
       {
          MiFlushTlb((PULONG)Pt, Address);
@@ -1382,7 +1382,7 @@
       do
       {
          Pte = *Pt;
-      } while (Pte != InterlockedCompareExchange(Pt, Pte | PA_DIRTY, Pte));
+      } while (Pte != InterlockedCompareExchangeUL(Pt, Pte | PA_DIRTY, Pte));
       if (!(Pte & PA_DIRTY))
       {
          MiFlushTlb(Pt, Address);
@@ -1412,7 +1412,7 @@
       {
          Pte = *Pt;
 	 tmpPte = Pte | PA_PRESENT;
-      } while (Pte != ExfInterlockedCompareExchange64(Pt, &tmpPte, &Pte));
+      } while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
       if (!(Pte & PA_PRESENT))
       {
          MiFlushTlb((PULONG)Pt, Address);
@@ -1436,7 +1436,7 @@
       do
       {
          Pte = *Pt;
-      } while (Pte != InterlockedCompareExchange(Pt, Pte | PA_PRESENT, Pte));
+      } while (Pte != InterlockedCompareExchangeUL(Pt, Pte | PA_PRESENT, Pte));
       if (!(Pte & PA_PRESENT))
       {
          MiFlushTlb(Pt, Address);
@@ -1546,7 +1546,7 @@
 	 {
 	    Pte |= 0x8000000000000000LL;
 	 }
-         Pte = ExfpInterlockedExchange64(Pt, &Pte);
+         Pte = ExfpInterlockedExchange64UL(Pt, &Pte);
          if (Pte != 0LL)
          {
             KEBUGCHECK(0);
@@ -1635,7 +1635,7 @@
          KEBUGCHECK(0);
       }
       tmpPte = SwapEntry << 1;
-      Pte = ExfpInterlockedExchange64(Pt, &tmpPte);
+      Pte = ExfpInterlockedExchange64UL(Pt, &tmpPte);
       if (PAE_PAGE_MASK((Pte)) != 0)
       {
          MmMarkPageUnmapped(PAE_PTE_TO_PFN((Pte)));
@@ -1793,7 +1793,7 @@
 	 {
 	    tmpPte |= 0x8000000000000000LL;
 	 }
-         Pte = ExfpInterlockedExchange64(Pt, &tmpPte);
+         Pte = ExfpInterlockedExchange64UL(Pt, &tmpPte);
          if (PAE_PAGE_MASK((Pte)) != 0LL && !((Pte) & PA_PRESENT))
          {
             KEBUGCHECK(0);
@@ -2014,7 +2014,7 @@
 	{
 	   tmpPte &= ~0x8000000000000000LL;
 	}
-      } while (Pte != ExfInterlockedCompareExchange64(Pt, &tmpPte, &Pte));
+      } while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
 
       MiFlushTlb((PULONG)Pt, Address);
    }
@@ -2124,7 +2124,7 @@
          {
             if (i * 512 + Offset < PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) || i * 512 + Offset >= PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP)+4)
             {
-               ExfInterlockedCompareExchange64(&Pde[Offset], &MmGlobalKernelPageDirectoryForPAE[i*512 + Offset], &ZeroPde);
+               ExfInterlockedCompareExchange64UL(&Pde[Offset], &MmGlobalKernelPageDirectoryForPAE[i*512 + Offset], &ZeroPde);
             }
          }
          MmUnmapPageTable((PULONG)Pde);
@@ -2148,7 +2148,7 @@
       {
          if (Offset != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP))
          {
-            InterlockedCompareExchange(&Pde[Offset], MmGlobalKernelPageDirectory[Offset], 0);
+            InterlockedCompareExchangeUL(&Pde[Offset], MmGlobalKernelPageDirectory[Offset], 0);
          }
       }
       if (Pde != (PULONG)PAGEDIRECTORY_MAP)
@@ -2170,7 +2170,7 @@
          if ((i < PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) || i >= PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) + 4) &&
              0LL == MmGlobalKernelPageDirectoryForPAE[i] && 0LL != CurrentPageDirectory[i])
          {
-            ExfpInterlockedExchange64(&MmGlobalKernelPageDirectoryForPAE[i], &CurrentPageDirectory[i]);
+            ExfpInterlockedExchange64UL(&MmGlobalKernelPageDirectoryForPAE[i], &CurrentPageDirectory[i]);
 	    if (Ke386GlobalPagesEnabled)
 	    {
                MmGlobalKernelPageDirectoryForPAE[i] |= PA_GLOBAL;
CVSspam 0.2.8