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