KD System Rewrite:
[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 extern NTSTATUS NTAPI Elf64FmtCreateSection
15 (
16 IN CONST VOID * FileHeader,
17 IN SIZE_T FileHeaderSize,
18 IN PVOID File,
19 OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
20 OUT PULONG Flags,
21 IN PEXEFMT_CB_READ_FILE ReadFileCb,
22 IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
23 );
24
25 NTSTATUS NTAPI ElfFmtCreateSection
26 (
27 IN CONST VOID * FileHeader,
28 IN SIZE_T FileHeaderSize,
29 IN PVOID File,
30 OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
31 OUT PULONG Flags,
32 IN PEXEFMT_CB_READ_FILE ReadFileCb,
33 IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
34 )
35 {
36 ULONG nDataType;
37 const Elf32_Ehdr * pehTempHeader;
38
39 ASSERT(FileHeader);
40 ASSERT(FileHeaderSize > 0);
41 ASSERT(Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize));
42 ASSERT(File);
43 ASSERT(ImageSectionObject);
44 ASSERT(Flags);
45 ASSERT(ReadFileCb);
46 ASSERT(AllocateSegmentsCb);
47
48 pehTempHeader = FileHeader;
49 ASSERT(((ULONG_PTR)pehTempHeader % TYPE_ALIGNMENT(Elf32_Ehdr)) == 0);
50 ASSERT(((ULONG_PTR)pehTempHeader % TYPE_ALIGNMENT(Elf64_Ehdr)) == 0);
51
52 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_ident));
53
54 /* File too small to be identified */
55 if(!RTL_CONTAINS_FIELD(pehTempHeader, FileHeaderSize, e_ident[EI_MAG3]))
56 return STATUS_ROS_EXEFMT_UNKNOWN_FORMAT;
57
58 /* Not an ELF file */
59 if
60 (
61 pehTempHeader->e_ident[EI_MAG0] != ELFMAG0 ||
62 pehTempHeader->e_ident[EI_MAG1] != ELFMAG1 ||
63 pehTempHeader->e_ident[EI_MAG2] != ELFMAG2 ||
64 pehTempHeader->e_ident[EI_MAG3] != ELFMAG3
65 )
66 return STATUS_ROS_EXEFMT_UNKNOWN_FORMAT;
67
68 /* Validate the data type */
69 nDataType = pehTempHeader->e_ident[EI_DATA];
70
71 switch(nDataType)
72 {
73 case ELFDATA2LSB:
74 case ELFDATA2MSB:
75 break;
76
77 default:
78 return STATUS_INVALID_IMAGE_FORMAT;
79 }
80
81 /* Validate the version */
82 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_version));
83
84 if
85 (
86 pehTempHeader->e_ident[EI_VERSION] != EV_CURRENT ||
87 ElfFmtpReadULong(pehTempHeader->e_version, nDataType) != EV_CURRENT
88 )
89 return STATUS_INVALID_IMAGE_FORMAT;
90
91 /* Validate the file type */
92 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_type));
93
94 switch(ElfFmtpReadUShort(pehTempHeader->e_type, nDataType))
95 {
96 case ET_DYN: ImageSectionObject->ImageCharacteristics |= IMAGE_FILE_DLL;
97 case ET_EXEC: break;
98 default: return STATUS_INVALID_IMAGE_FORMAT;
99 }
100
101 /* Convert the target machine */
102 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_machine));
103 ASSERT(ImageSectionObject->Machine == IMAGE_FILE_MACHINE_UNKNOWN);
104
105 switch(ElfFmtpReadUShort(pehTempHeader->e_machine, nDataType))
106 {
107 case EM_386: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_I386; break;
108 case EM_MIPS_RS3_LE: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_R3000; break;
109
110 #if 0
111 /* TODO: need to read e_flags for full identification */
112 case EM_SH: break;
113 #endif
114
115 case EM_ARM: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_ARM; break;
116 case EM_PPC: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_POWERPC; break;
117 case EM_IA_64: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_IA64; break;
118 case EM_ALPHA: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_AXP64; break;
119 case EM_X86_64: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_AMD64; break;
120 case EM_M32R: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_M32R; break;
121 }
122
123 /* Call the appropriate handler for the class-specific fields */
124 switch(pehTempHeader->e_ident[EI_CLASS])
125 {
126 case ELFCLASS32:
127 return Elf32FmtCreateSection
128 (
129 FileHeader,
130 FileHeaderSize,
131 File,
132 ImageSectionObject,
133 Flags,
134 ReadFileCb,
135 AllocateSegmentsCb
136 );
137
138 case ELFCLASS64:
139 return Elf64FmtCreateSection
140 (
141 FileHeader,
142 FileHeaderSize,
143 File,
144 ImageSectionObject,
145 Flags,
146 ReadFileCb,
147 AllocateSegmentsCb
148 );
149 }
150
151 /* Unknown class */
152 return STATUS_INVALID_IMAGE_FORMAT;
153 }
154
155 /* EOF */