2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/mm/elf32.c
5 * PURPOSE: No purpose listed.
7 * PROGRAMMERS: No programmer listed.
10 #define __ELF_WORD_SIZE 32
13 extern NTSTATUS NTAPI Elf64FmtCreateSection
15 IN CONST VOID
* FileHeader
,
16 IN SIZE_T FileHeaderSize
,
18 OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject
,
20 IN PEXEFMT_CB_READ_FILE ReadFileCb
,
21 IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
24 NTSTATUS NTAPI ElfFmtCreateSection
26 IN CONST VOID
* FileHeader
,
27 IN SIZE_T FileHeaderSize
,
29 OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject
,
31 IN PEXEFMT_CB_READ_FILE ReadFileCb
,
32 IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
36 const Elf32_Ehdr
* pehTempHeader
;
39 ASSERT(FileHeaderSize
> 0);
40 ASSERT(Intsafe_CanOffsetPointer(FileHeader
, FileHeaderSize
));
42 ASSERT(ImageSectionObject
);
45 ASSERT(AllocateSegmentsCb
);
47 pehTempHeader
= FileHeader
;
48 ASSERT(((ULONG_PTR
)pehTempHeader
% TYPE_ALIGNMENT(Elf32_Ehdr
)) == 0);
49 ASSERT(((ULONG_PTR
)pehTempHeader
% TYPE_ALIGNMENT(Elf64_Ehdr
)) == 0);
51 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr
, Elf64_Ehdr
, e_ident
));
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
;
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
65 return STATUS_ROS_EXEFMT_UNKNOWN_FORMAT
;
67 /* Validate the data type */
68 nDataType
= pehTempHeader
->e_ident
[EI_DATA
];
77 return STATUS_INVALID_IMAGE_FORMAT
;
80 /* Validate the version */
81 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr
, Elf64_Ehdr
, e_version
));
85 pehTempHeader
->e_ident
[EI_VERSION
] != EV_CURRENT
||
86 ElfFmtpReadULong(pehTempHeader
->e_version
, nDataType
) != EV_CURRENT
88 return STATUS_INVALID_IMAGE_FORMAT
;
90 /* Validate the file type */
91 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr
, Elf64_Ehdr
, e_type
));
93 switch(ElfFmtpReadUShort(pehTempHeader
->e_type
, nDataType
))
95 case ET_DYN
: ImageSectionObject
->ImageCharacteristics
|= IMAGE_FILE_DLL
;
97 default: return STATUS_INVALID_IMAGE_FORMAT
;
100 /* Convert the target machine */
101 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr
, Elf64_Ehdr
, e_machine
));
102 ASSERT(ImageSectionObject
->Machine
== IMAGE_FILE_MACHINE_UNKNOWN
);
104 switch(ElfFmtpReadUShort(pehTempHeader
->e_machine
, nDataType
))
106 case EM_386
: ImageSectionObject
->Machine
= IMAGE_FILE_MACHINE_I386
; break;
107 case EM_MIPS_RS3_LE
: ImageSectionObject
->Machine
= IMAGE_FILE_MACHINE_R3000
; break;
110 /* TODO: need to read e_flags for full identification */
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;
122 /* Call the appropriate handler for the class-specific fields */
123 switch(pehTempHeader
->e_ident
[EI_CLASS
])
126 return Elf32FmtCreateSection
138 return Elf64FmtCreateSection
151 return STATUS_INVALID_IMAGE_FORMAT
;