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 #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
19 extern NTSTATUS NTAPI Elf64FmtCreateSection
21 IN CONST VOID
* FileHeader
,
22 IN SIZE_T FileHeaderSize
,
24 OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject
,
26 IN PEXEFMT_CB_READ_FILE ReadFileCb
,
27 IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
30 NTSTATUS NTAPI ElfFmtCreateSection
32 IN CONST VOID
* FileHeader
,
33 IN SIZE_T FileHeaderSize
,
35 OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject
,
37 IN PEXEFMT_CB_READ_FILE ReadFileCb
,
38 IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
42 const Elf32_Ehdr
* pehTempHeader
;
45 ASSERT(FileHeaderSize
> 0);
46 ASSERT(Intsafe_CanOffsetPointer(FileHeader
, FileHeaderSize
));
48 ASSERT(ImageSectionObject
);
51 ASSERT(AllocateSegmentsCb
);
53 pehTempHeader
= FileHeader
;
54 ASSERT(((ULONG_PTR
)pehTempHeader
% TYPE_ALIGNMENT(Elf32_Ehdr
)) == 0);
55 ASSERT(((ULONG_PTR
)pehTempHeader
% TYPE_ALIGNMENT(Elf64_Ehdr
)) == 0);
57 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr
, Elf64_Ehdr
, e_ident
));
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
;
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
71 return STATUS_ROS_EXEFMT_UNKNOWN_FORMAT
;
73 /* Validate the data type */
74 nDataType
= pehTempHeader
->e_ident
[EI_DATA
];
83 return STATUS_INVALID_IMAGE_FORMAT
;
86 /* Validate the version */
87 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr
, Elf64_Ehdr
, e_version
));
91 pehTempHeader
->e_ident
[EI_VERSION
] != EV_CURRENT
||
92 ElfFmtpReadULong(pehTempHeader
->e_version
, nDataType
) != EV_CURRENT
94 return STATUS_INVALID_IMAGE_FORMAT
;
96 /* Validate the file type */
97 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr
, Elf64_Ehdr
, e_type
));
99 switch(ElfFmtpReadUShort(pehTempHeader
->e_type
, nDataType
))
101 case ET_DYN
: ImageSectionObject
->ImageCharacteristics
|= IMAGE_FILE_DLL
;
103 default: return STATUS_INVALID_IMAGE_FORMAT
;
106 /* Convert the target machine */
107 ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr
, Elf64_Ehdr
, e_machine
));
108 ASSERT(ImageSectionObject
->Machine
== IMAGE_FILE_MACHINE_UNKNOWN
);
110 switch(ElfFmtpReadUShort(pehTempHeader
->e_machine
, nDataType
))
112 case EM_386
: ImageSectionObject
->Machine
= IMAGE_FILE_MACHINE_I386
; break;
113 case EM_MIPS_RS3_LE
: ImageSectionObject
->Machine
= IMAGE_FILE_MACHINE_R3000
; break;
116 /* TODO: need to read e_flags for full identification */
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;
128 /* Call the appropriate handler for the class-specific fields */
129 switch(pehTempHeader
->e_ident
[EI_CLASS
])
132 return Elf32FmtCreateSection
144 return Elf64FmtCreateSection
157 return STATUS_INVALID_IMAGE_FORMAT
;