From 854ff3471b3d1e4b4467d9a2a0da68b2f1cd6287 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sun, 6 Jun 2010 04:38:51 +0000 Subject: [PATCH] [NTOS]: Clean up /mm a bit, move sysldr.c into ARM3. svn path=/trunk/; revision=47608 --- reactos/ntoskrnl/mm/{ => ARM3}/sysldr.c | 2 +- reactos/ntoskrnl/mm/elf.inc.h | 705 ----------------------- reactos/ntoskrnl/mm/elf32.c | 154 ----- reactos/ntoskrnl/mm/elf64.c | 11 - reactos/ntoskrnl/ntoskrnl-generic.rbuild | 2 +- 5 files changed, 2 insertions(+), 872 deletions(-) rename reactos/ntoskrnl/mm/{ => ARM3}/sysldr.c (99%) delete mode 100644 reactos/ntoskrnl/mm/elf.inc.h delete mode 100644 reactos/ntoskrnl/mm/elf32.c delete mode 100644 reactos/ntoskrnl/mm/elf64.c diff --git a/reactos/ntoskrnl/mm/sysldr.c b/reactos/ntoskrnl/mm/ARM3/sysldr.c similarity index 99% rename from reactos/ntoskrnl/mm/sysldr.c rename to reactos/ntoskrnl/mm/ARM3/sysldr.c index a242b4b2f6c..2c4a09cfd3a 100644 --- a/reactos/ntoskrnl/mm/sysldr.c +++ b/reactos/ntoskrnl/mm/ARM3/sysldr.c @@ -15,7 +15,7 @@ #line 16 "ARM³::LOADER" #define MODULE_INVOLVED_IN_ARM3 -#include "./ARM3/miarm.h" +#include "../ARM3/miarm.h" /* GCC's incompetence strikes again */ __inline diff --git a/reactos/ntoskrnl/mm/elf.inc.h b/reactos/ntoskrnl/mm/elf.inc.h deleted file mode 100644 index 2360bffd1d2..00000000000 --- a/reactos/ntoskrnl/mm/elf.inc.h +++ /dev/null @@ -1,705 +0,0 @@ -#define NDEBUG -#include - -#include - -#ifndef __ELF_WORD_SIZE -#error __ELF_WORD_SIZE must be defined -#endif - -#include - -/* 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 -) -{ - return Addend1 <= (MAXULONG_PTR - Addend2); -} - -#define Intsafe_CanAddSizeT Intsafe_CanAddULongPtr - -static __inline BOOLEAN Intsafe_CanAddULong32 -( - IN ULONG Addend1, - IN ULONG Addend2 -) -{ - return Addend1 <= (MAXULONG - Addend2); -} - -static __inline BOOLEAN Intsafe_AddULong32 -( - OUT PULONG32 Result, - IN ULONG Addend1, - IN ULONG Addend2 -) -{ - if(!Intsafe_CanAddULong32(Addend1, Addend2)) - return FALSE; - - *Result = Addend1 + Addend2; - return TRUE; -} - -static __inline BOOLEAN Intsafe_CanAddULong64 -( - IN ULONG64 Addend1, - IN ULONG64 Addend2 -) -{ - return Addend1 <= (((ULONG64)-1) - Addend2); -} - -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 __inline BOOLEAN Intsafe_CanMulULong32 -( - IN ULONG Factor1, - IN ULONG Factor2 -) -{ - return Factor1 <= (MAXULONG / Factor2); -} - -static __inline BOOLEAN Intsafe_MulULong32 -( - OUT PULONG32 Result, - IN ULONG Factor1, - IN ULONG Factor2 -) -{ - if(!Intsafe_CanMulULong32(Factor1, Factor2)) - return FALSE; - - *Result = Factor1 * Factor2; - return TRUE; -} - -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_) \ - ((ULONG_PTR)(P_) + (ULONG_PTR)(SIZE_) > (ULONG_PTR)&((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 -) -{ - PUCHAR p; - - if(DataType == ELF_TARG_DATA) - return Input; - - p = (PUCHAR)&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]); - } - - ASSERT(FALSE); - return (ULONG64)-1; -} - -static __inline ULONG ElfFmtpReadULong -( - IN ULONG Input, - IN ULONG DataType -) -{ - PUCHAR p; - - if(DataType == ELF_TARG_DATA) - return Input; - - p = (PUCHAR)&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 MAXULONG; -} - -static __inline USHORT ElfFmtpReadUShort -( - IN USHORT Input, - IN ULONG DataType -) -{ - PUCHAR p; - - if(DataType == ELF_TARG_DATA) - return Input; - - p = (PUCHAR)&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; -} - -static __inline ULONG64 ElfFmtpSafeReadULong64 -( - IN CONST ULONG64 * Input, - IN ULONG DataType -) -{ - PUCHAR p; - ULONG64 nSafeInput; - - RtlRetrieveUlonglong(&nSafeInput, Input); - - p = (PUCHAR)&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 ULONG32 * Input, - IN ULONG DataType -) -{ - PUCHAR p; - ULONG nSafeInput; - union - { - CONST ULONG32 *ConstInput; - ULONG32 *Input; - }pInput = {Input}; - - RtlRetrieveUlong(&nSafeInput, pInput.Input); - - if(DataType == ELF_TARG_DATA) - return nSafeInput; - - p = (PUCHAR)&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 MAXULONG; -} - -static __inline BOOLEAN ElfFmtpIsPowerOf2(IN Elf_Addr Number) -{ - if(Number == 0) - return FALSE; - - return (Number & (Number - 1)) == 0; -} - -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 -) -{ - ASSERT(sizeof(Elf_Addr) == sizeof(Elf_Size)); - ASSERT(sizeof(Elf_Addr) == sizeof(Elf_Off)); - ASSERT(ElfFmtpIsPowerOf2(Alignment)); - return Address & ~(Alignment - 1); -} - -static __inline BOOLEAN ElfFmtpAlignUp -( - OUT Elf_Addr * AlignedAddress, - IN Elf_Addr Address, - IN Elf_Addr Alignment -) -{ - 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 = 0; - Elf_Addr nEntryPoint; - ULONG32 nPrevVirtualEndOfSegment = 0; - 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 = 0; - Elf_Size nFileSize = 0; - - 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 */ - /* - 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; - - /* - FIXME: see the TODO above. This is the safest way to load ELF drivers, for - now, if a bit wasteful of memory - */ - pssSegments[j].Characteristics |= IMAGE_SCN_MEM_NOT_PAGED; - - /* 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; - - nEntryPoint = ElfFmtpReadAddr(pehHeader->e_entry, nData); - - if(nEntryPoint < nImageBase || nEntryPoint - nImageBase > nPrevVirtualEndOfSegment) - DIE(("Entry point not within the virtual image\n")); - - ASSERT(nEntryPoint >= nImageBase); - ASSERT((nEntryPoint - nImageBase) <= MAXULONG); - ImageSectionObject->EntryPoint = nEntryPoint - nImageBase; - - /* TODO: support Wine executables and read these values from nt_headers */ - ImageSectionObject->ImageCharacteristics |= - IMAGE_FILE_EXECUTABLE_IMAGE | - IMAGE_FILE_LINE_NUMS_STRIPPED | - IMAGE_FILE_LOCAL_SYMS_STRIPPED | - (nImageBase > MAXULONG ? IMAGE_FILE_LARGE_ADDRESS_AWARE : 0) | - IMAGE_FILE_DEBUG_STRIPPED; - - if(nData == ELFDATA2LSB) - ImageSectionObject->ImageCharacteristics |= IMAGE_FILE_BYTES_REVERSED_LO; - else if(nData == ELFDATA2MSB) - ImageSectionObject->ImageCharacteristics |= IMAGE_FILE_BYTES_REVERSED_HI; - - /* Base address outside the possible address space */ - if(nImageBase > MAXULONG_PTR) - ImageSectionObject->ImageBase = EXEFMT_LOAD_BASE_NONE; - /* Position-independent image, base address doesn't matter */ - else if(nImageBase == 0) - ImageSectionObject->ImageBase = EXEFMT_LOAD_BASE_ANY; - /* Use the specified base address */ - else - ImageSectionObject->ImageBase = (ULONG_PTR)nImageBase; - - /* safest bet */ - ImageSectionObject->Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; - ImageSectionObject->MinorSubsystemVersion = 0; - ImageSectionObject->MajorSubsystemVersion = 4; - - /* Success, at last */ - nStatus = STATUS_SUCCESS; - -l_Return: - if(pBuffer) - ExFreePool(pBuffer); - - return nStatus; -} - -/* EOF */ diff --git a/reactos/ntoskrnl/mm/elf32.c b/reactos/ntoskrnl/mm/elf32.c deleted file mode 100644 index 4e56e4408fc..00000000000 --- a/reactos/ntoskrnl/mm/elf32.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/mm/elf32.c - * PURPOSE: No purpose listed. - * - * PROGRAMMERS: No programmer listed. - */ -#include -#define __ELF_WORD_SIZE 32 -#include "elf.inc.h" - -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 */ diff --git a/reactos/ntoskrnl/mm/elf64.c b/reactos/ntoskrnl/mm/elf64.c deleted file mode 100644 index 783f5a00534..00000000000 --- a/reactos/ntoskrnl/mm/elf64.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/mm/elf64.c - * PURPOSE: No purpose listed. - * - * PROGRAMMERS: No programmer listed. - */ -#include -#define __ELF_WORD_SIZE 64 -#include "elf.inc.h" diff --git a/reactos/ntoskrnl/ntoskrnl-generic.rbuild b/reactos/ntoskrnl/ntoskrnl-generic.rbuild index 5dc63c62e56..68ad293fe9d 100644 --- a/reactos/ntoskrnl/ntoskrnl-generic.rbuild +++ b/reactos/ntoskrnl/ntoskrnl-generic.rbuild @@ -404,6 +404,7 @@ pfnlist.c pool.c procsup.c + sysldr.c syspte.c virtual.c @@ -425,7 +426,6 @@ region.c rmap.c section.c - sysldr.c virtual.c elf32.c