3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/mm/elf32.c
6 * PURPOSE: No purpose listed.
8 * PROGRAMMERS: No programmer listed.
11 #define __ELF_WORD_SIZE 32
14 extern NTSTATUS NTAPI Elf64FmtCreateSection
16 IN CONST VOID
* FileHeader
,
17 IN SIZE_T FileHeaderSize
,
19 OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject
,
21 IN PEXEFMT_CB_READ_FILE ReadFileCb
,
22 IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
25 NTSTATUS NTAPI ElfFmtCreateSection
27 IN CONST VOID
* FileHeader
,
28 IN SIZE_T FileHeaderSize
,
30 OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject
,
32 IN PEXEFMT_CB_READ_FILE ReadFileCb
,
33 IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
37 const Elf32_Ehdr
* pehTempHeader
;
40 ASSERT(FileHeaderSize
> 0);
41 ASSERT(Intsafe_CanOffsetPointer(FileHeader
, FileHeaderSize
));
43 ASSERT(ImageSectionObject
);
46 ASSERT(AllocateSegmentsCb
);
48 pehTempHeader
= FileHeader
;
49 ASSERT(((ULONG_PTR
)pehTempHeader
% TYPE_ALIGNMENT(Elf32_Ehdr
)) == 0);
50 ASSERT(((ULONG_PTR
)pehTempHeader
% TYPE_ALIGNMENT(Elf64_Ehdr
)) == 0);
52 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr
, Elf64_Ehdr
, e_ident
));
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
;
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
66 return STATUS_ROS_EXEFMT_UNKNOWN_FORMAT
;
68 /* Validate the data type */
69 nDataType
= pehTempHeader
->e_ident
[EI_DATA
];
78 return STATUS_INVALID_IMAGE_FORMAT
;
81 /* Validate the version */
82 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr
, Elf64_Ehdr
, e_version
));
86 pehTempHeader
->e_ident
[EI_VERSION
] != EV_CURRENT
||
87 ElfFmtpReadULong(pehTempHeader
->e_version
, nDataType
) != EV_CURRENT
89 return STATUS_INVALID_IMAGE_FORMAT
;
91 /* Validate the file type */
92 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr
, Elf64_Ehdr
, e_type
));
94 switch(ElfFmtpReadUShort(pehTempHeader
->e_type
, nDataType
))
96 case ET_DYN
: ImageSectionObject
->ImageCharacteristics
|= IMAGE_FILE_DLL
;
98 default: return STATUS_INVALID_IMAGE_FORMAT
;
101 /* Convert the target machine */
102 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr
, Elf64_Ehdr
, e_machine
));
103 ASSERT(ImageSectionObject
->Machine
== IMAGE_FILE_MACHINE_UNKNOWN
);
105 switch(ElfFmtpReadUShort(pehTempHeader
->e_machine
, nDataType
))
107 case EM_386
: ImageSectionObject
->Machine
= IMAGE_FILE_MACHINE_I386
; break;
108 case EM_MIPS_RS3_LE
: ImageSectionObject
->Machine
= IMAGE_FILE_MACHINE_R3000
; break;
111 /* TODO: need to read e_flags for full identification */
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;
123 /* Call the appropriate handler for the class-specific fields */
124 switch(pehTempHeader
->e_ident
[EI_CLASS
])
127 return Elf32FmtCreateSection
139 return Elf64FmtCreateSection
152 return STATUS_INVALID_IMAGE_FORMAT
;