implemented sweeping of handle tables
[reactos.git] / reactos / ntoskrnl / mm / elf32.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/mm/elf32.c
6 * PURPOSE: No purpose listed.
7 *
8 * PROGRAMMERS: No programmer listed.
9 */
10
11 #define __ELF_WORD_SIZE 32
12 #include "elf.inc.h"
13
14 #define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM little-endian
15 #define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64
16 #define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // Alpha AXP, full 64-bit support
17 #define IMAGE_FILE_MACHINE_M32R 0x9041 // M32R little-endian
18
19 extern NTSTATUS NTAPI Elf64FmtCreateSection
20 (
21 IN CONST VOID * FileHeader,
22 IN SIZE_T FileHeaderSize,
23 IN PVOID File,
24 OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
25 OUT PULONG Flags,
26 IN PEXEFMT_CB_READ_FILE ReadFileCb,
27 IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
28 );
29
30 NTSTATUS NTAPI ElfFmtCreateSection
31 (
32 IN CONST VOID * FileHeader,
33 IN SIZE_T FileHeaderSize,
34 IN PVOID File,
35 OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
36 OUT PULONG Flags,
37 IN PEXEFMT_CB_READ_FILE ReadFileCb,
38 IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
39 )
40 {
41 ULONG nDataType;
42 const Elf32_Ehdr * pehTempHeader;
43
44 ASSERT(FileHeader);
45 ASSERT(FileHeaderSize > 0);
46 ASSERT(Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize));
47 ASSERT(File);
48 ASSERT(ImageSectionObject);
49 ASSERT(Flags);
50 ASSERT(ReadFileCb);
51 ASSERT(AllocateSegmentsCb);
52
53 pehTempHeader = FileHeader;
54 ASSERT(((ULONG_PTR)pehTempHeader % TYPE_ALIGNMENT(Elf32_Ehdr)) == 0);
55 ASSERT(((ULONG_PTR)pehTempHeader % TYPE_ALIGNMENT(Elf64_Ehdr)) == 0);
56
57 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_ident));
58
59 /* File too small to be identified */
60 if(!RTL_CONTAINS_FIELD(pehTempHeader, FileHeaderSize, e_ident[EI_MAG3]))
61 return STATUS_ROS_EXEFMT_UNKNOWN_FORMAT;
62
63 /* Not an ELF file */
64 if
65 (
66 pehTempHeader->e_ident[EI_MAG0] != ELFMAG0 ||
67 pehTempHeader->e_ident[EI_MAG1] != ELFMAG1 ||
68 pehTempHeader->e_ident[EI_MAG2] != ELFMAG2 ||
69 pehTempHeader->e_ident[EI_MAG3] != ELFMAG3
70 )
71 return STATUS_ROS_EXEFMT_UNKNOWN_FORMAT;
72
73 /* Validate the data type */
74 nDataType = pehTempHeader->e_ident[EI_DATA];
75
76 switch(nDataType)
77 {
78 case ELFDATA2LSB:
79 case ELFDATA2MSB:
80 break;
81
82 default:
83 return STATUS_INVALID_IMAGE_FORMAT;
84 }
85
86 /* Validate the version */
87 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_version));
88
89 if
90 (
91 pehTempHeader->e_ident[EI_VERSION] != EV_CURRENT ||
92 ElfFmtpReadULong(pehTempHeader->e_version, nDataType) != EV_CURRENT
93 )
94 return STATUS_INVALID_IMAGE_FORMAT;
95
96 /* Validate the file type */
97 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_type));
98
99 switch(ElfFmtpReadUShort(pehTempHeader->e_type, nDataType))
100 {
101 case ET_DYN: ImageSectionObject->ImageCharacteristics |= IMAGE_FILE_DLL;
102 case ET_EXEC: break;
103 default: return STATUS_INVALID_IMAGE_FORMAT;
104 }
105
106 /* Convert the target machine */
107 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_machine));
108 ASSERT(ImageSectionObject->Machine == IMAGE_FILE_MACHINE_UNKNOWN);
109
110 switch(ElfFmtpReadUShort(pehTempHeader->e_machine, nDataType))
111 {
112 case EM_386: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_I386; break;
113 case EM_MIPS_RS3_LE: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_R3000; break;
114
115 #if 0
116 /* TODO: need to read e_flags for full identification */
117 case EM_SH: break;
118 #endif
119
120 case EM_ARM: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_ARM; break;
121 case EM_PPC: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_POWERPC; break;
122 case EM_IA_64: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_IA64; break;
123 case EM_ALPHA: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_AXP64; break;
124 case EM_X86_64: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_AMD64; break;
125 case EM_M32R: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_M32R; break;
126 }
127
128 /* Call the appropriate handler for the class-specific fields */
129 switch(pehTempHeader->e_ident[EI_CLASS])
130 {
131 case ELFCLASS32:
132 return Elf32FmtCreateSection
133 (
134 FileHeader,
135 FileHeaderSize,
136 File,
137 ImageSectionObject,
138 Flags,
139 ReadFileCb,
140 AllocateSegmentsCb
141 );
142
143 case ELFCLASS64:
144 return Elf64FmtCreateSection
145 (
146 FileHeader,
147 FileHeaderSize,
148 File,
149 ImageSectionObject,
150 Flags,
151 ReadFileCb,
152 AllocateSegmentsCb
153 );
154 }
155
156 /* Unknown class */
157 return STATUS_INVALID_IMAGE_FORMAT;
158 }
159
160 /* EOF */