2 added + 14 modified, total 16 files
reactos/include/elf
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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