Hi!
I have attached a elf.h file (to be put into the toplevel include directory) with ELF structures/constants and a patch for ntoskrnl/mm/section.c which should add support for mapping ELF files with NtCreateSection. It is completly untested I think.
We also have to port a runtime linker (rtld) - it has to be statically linked/use only syscalls because if an ELF file contains an interpreter name (on linux something like /lib/rtld-elf.so) the kernel usually maps the interpreter instead (or additionally) and begins execution at the interpreter's entry point, passing it a file handle or the base address of the file to be linked & ran and the interpreter does the rest.
- blight
#ifndef __INCLUDE_ELF_H #define __INCLUDE_ELF_H
#ifdef __64BITS__ /* FIXME: how to check for 64 bits? */ # define ELF_ARCH_SIZE 64 #else # define ELF_ARCH_SIZE 32 #endif
/* 32-bit data types */ typedef unsigned long ELF32_ADDR; /* Unsigned program address */ typedef unsigned short ELF32_HALF; /* Unsigned medium integer */ typedef unsigned long ELF32_OFF; /* Unsigned file offset */ typedef unsigned long ELF32_SWORD; /* Signed large integer */ typedef unsigned long ELF32_WORD; /* Unsigned large integer */ typedef ELF32_OFF ELF32_HASHELT; /* Hash element? */
/* Elf data encodings */ #define IMAGE_ELF_DATA_NONE 0 /* Invalid data encoding */ #define IMAGE_ELF_DATA_2LSB 1 /* 2's complement, LSB first */ #define IMAGE_ELF_DATA_2MSB 2 /* 2's complement, MSB first */
/* Elf object file types */ #define IMAGE_ELF_TYPE_NONE 0 /* No file type */ #define IMAGE_ELF_TYPE_REL 1 /* Relocatable file */ #define IMAGE_ELF_TYPE_EXEC 2 /* Executable file */ #define IMAGE_ELF_TYPE_DYN 3 /* Shared object file */ #define IMAGE_ELF_TYPE_CORE 4 /* Core file */
/* Elf machines */ #define IMAGE_ELF_MACHINE_NONE 0 /* No machine */ #define IMAGE_ELF_MACHINE_M32 1 /* AT&T WE 32100 */ #define IMAGE_ELF_MACHINE_SPARC 2 /* SPARC */ #define IMAGE_ELF_MACHINE_386 3 /* Intel 80386 */ #define IMAGE_ELF_MACHINE_68K 4 /* Motorola 68000 */ #define IMAGE_ELF_MACHINE_88K 5 /* Motorola 88000 */ /* 6 is reserved */ #define IMAGE_ELF_MACHINE_860 7 /* Intel 80860 */ #define IMAGE_ELF_MACHINE_MIPS 8 /* MIPS RS3000 (MIPS I) */ #define IMAGE_ELF_MACHINE_S370 9 /* IBM System/370 Processor */ #define IMAGE_ELF_MACHINE_MIPS_RS3_LE 10 /* MIPS RS3000 Little-endian */ /* 11-14 are reserved */ #define IMAGE_ELF_MACHINE_PARISC 15 /* Hewlett-Packard PA-RISC */ /* 16 is reserved */ #define IMAGE_ELF_MACHINE_VPP500 17 /* Fujitsu VPP500 */ #define IMAGE_ELF_MACHINE_SPARC32PLUS 18 /* Enhanced instruction set SPARC */ #define IMAGE_ELF_MACHINE_960 19 /* Intel 80960 */ #define IMAGE_ELF_MACHINE_PPC 20 /* PowerPC */ #define IMAGE_ELF_MACHINE_PPC64 21 /* 64-bit PowerPC */ /* 22-35 are reserved */ #define IMAGE_ELF_MACHINE_V800 36 /* NEC V800 */ #define IMAGE_ELF_MACHINE_FR20 37 /* Fujitsu FR20 */ #define IMAGE_ELF_MACHINE_RH32 38 /* TRW RH-32 */ #define IMAGE_ELF_MACHINE_RCE 39 /* Motorola RCE */ #define IMAGE_ELF_MACHINE_ARM 40 /* Advanced RISC Machines ARM */ #define IMAGE_ELF_MACHINE_ALPHA 41 /* Digital Alpha */ #define IMAGE_ELF_MACHINE_SH 42 /* Hitachi SH */ #define IMAGE_ELF_MACHINE_SPARCV9 43 /* SPARC Version 9 */ #define IMAGE_ELF_MACHINE_TRICORE 44 /* Siemens Tricore embedded processor */ #define IMAGE_ELF_MACHINE_ARC 45 /* Argonaut RISC Core, Argonaut Technologies Inc. */ #define IMAGE_ELF_MACHINE_H8_300 46 /* Hitachi H8/300 */ #define IMAGE_ELF_MACHINE_H8_300H 47 /* Hitachi H8/300H */ #define IMAGE_ELF_MACHINE_H8S 48 /* Hitachi H8S */ #define IMAGE_ELF_MACHINE_H8_500 49 /* Hitachi H8/500 */ #define IMAGE_ELF_MACHINE_IA_64 50 /* Intel IA-64 processor architecture */ #define IMAGE_ELF_MACHINE_MIPS_X 51 /* Stanford MIPS-X */ #define IMAGE_ELF_MACHINE_COLDFIRE 52 /* Motorola ColdFire */ #define IMAGE_ELF_MACHINE_68HC12 53 /* Motorola M68HC12 */ #define IMAGE_ELF_MACHINE_MMA 54 /* Fujitsu MMA Multimedia Accelerator */ #define IMAGE_ELF_MACHINE_PCP 55 /* Siemens PCP */ #define IMAGE_ELF_MACHINE_NCPU 56 /* Sony nCPU embedded RISC processor */ #define IMAGE_ELF_MACHINE_NDR1 57 /* Denso NDR1 microprocessor */ #define IMAGE_ELF_MACHINE_STARCORE 58 /* Motorola Star*Core processor */ #define IMAGE_ELF_MACHINE_ME16 59 /* Toyota ME16 processor */ #define IMAGE_ELF_MACHINE_ST100 60 /* STMicroelectronics ST100 processor */ #define IMAGE_ELF_MACHINE_TINYJ 61 /* Advanced Logic Corp. TinyJ embedded processor family */ /* 62-65 are reserved */ #define IMAGE_ELF_MACHINE_FX66 66 /* Siemens FX66 microcontroller */ #define IMAGE_ELF_MACHINE_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 bit microcontroller */ #define IMAGE_ELF_MACHINE_ST7 68 /* STMicroelectronics ST7 8-bit microcontroller */ #define IMAGE_ELF_MACHINE_68HC16 69 /* Motorola MC68HC16 Microcontroller */ #define IMAGE_ELF_MACHINE_68HC11 70 /* Motorola MC68HC11 Microcontroller */ #define IMAGE_ELF_MACHINE_68HC08 71 /* Motorola MC68HC08 Microcontroller */ #define IMAGE_ELF_MACHINE_68HC05 72 /* Motorola MC68HC05 Microcontroller */ #define IMAGE_ELF_MACHINE_SVX 73 /* Silicon Graphics SVx */ #define IMAGE_ELF_MACHINE_ST19 74 /* STMicroelectronics ST19 8-bit microcontroller */ #define IMAGE_ELF_MACHINE_VAX 75 /* Digital VAX */ #define IMAGE_ELF_MACHINE_CRIS 76 /* Axis Communications 32-bit embedded processor */ #define IMAGE_ELF_MACHINE_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ #define IMAGE_ELF_MACHINE_FIREPATH 78 /* Element 14 64-bit DSP Processor */ #define IMAGE_ELF_MACHINE_ZSP 79 /* LSI Logic 16-bit DSP Processor */ #define IMAGE_ELF_MACHINE_MMIX 80 /* Donald Knuth's educational 64-bit processor */ #define IMAGE_ELF_MACHINE_HUANY 81 /* Harvard University machine-independent object files */ #define IMAGE_ELF_MACHINE_PRISM 82 /* SiTera Prism */ #define IMAGE_ELF_MACHINE_AVR 83 /* Atmel AVR 8-bit microcontroller */ #define IMAGE_ELF_MACHINE_FR30 84 /* Fujitsu FR30 */ #define IMAGE_ELF_MACHINE_D10V 85 /* Mitsubishi D10V */ #define IMAGE_ELF_MACHINE_D30V 86 /* Mitsubishi D30V */ #define IMAGE_ELF_MACHINE_V850 87 /* NEC v850 */ #define IMAGE_ELF_MACHINE_M32R 88 /* Mitsubishi M32R */ #define IMAGE_ELF_MACHINE_MN10300 89 /* Matsushita MN10300 */ #define IMAGE_ELF_MACHINE_MN10200 90 /* Matsushita MN10200 */ #define IMAGE_ELF_MACHINE_PJ 91 /* picoJava */ #define IMAGE_ELF_MACHINE_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
/* Elf versions */ #define IMAGE_ELF_VERSION_NONE 0 /* Invalid version */ #define IMAGE_ELF_VERSION_CURRENT 1 /* Current version */
/* Elf identification */ #define IMAGE_ELF_SIZEOF_IDENT 16 #define IMAGE_ELF_IDENT_MAGIC0 0 /* Magic */ #define IMAGE_ELF_IDENT_MAGIC1 1 #define IMAGE_ELF_IDENT_MAGIC2 2 #define IMAGE_ELF_IDENT_MAGIC3 3 #define IMAGE_ELF_IDENT_CLASS 4 /* File class */ #define IMAGE_ELF_IDENT_DATA 5 /* Data encoding */ #define IMAGE_ELF_IDENT_VERSION 6 /* File version */ #define IMAGE_ELF_IDENT_OSABI 7 /* Operating system/ABI identification */ #define IMAGE_ELF_IDENT_ABIVERSION 8 /* ABI version */ #define IMAGE_ELF_IDENT_PAD 9 /* Start of padding bytes */
/* Magic numbers */ #define IMAGE_ELF_MAGIC0 0x7f #define IMAGE_ELF_MAGIC1 'E' #define IMAGE_ELF_MAGIC2 'L' #define IMAGE_ELF_MAGIC3 'F'
/* Elf file classes */ #define IMAGE_ELF_CLASS_NONE 0 /* Invalid class */ #define IMAGE_ELF_CLASS_32 1 /* 32-bit object */ #define IMAGE_ELF_CLASS_64 2 /* 64-bit object */
/* Check elf magic */ #define IMAGE_IS_ELF(hdr) ((hdr).Ident[IMAGE_ELF_IDENT_MAGIC0] == IMAGE_ELF_MAGIC0 && \ (hdr).Ident[IMAGE_ELF_IDENT_MAGIC1] == IMAGE_ELF_MAGIC1 && \ (hdr).Ident[IMAGE_ELF_IDENT_MAGIC2] == IMAGE_ELF_MAGIC2 && \ (hdr).Ident[IMAGE_ELF_IDENT_MAGIC3] == IMAGE_ELF_MAGIC3)
/* 32-bit Elf header */ typedef struct _IMAGE_ELF32_HEADER { unsigned char Ident[IMAGE_ELF_SIZEOF_IDENT]; /* Identification */ ELF32_HALF Type; /* Object file type */ ELF32_HALF Machine; /* Required architecture */ ELF32_WORD Version; /* Object file version */ ELF32_ADDR Entry; /* Virtual address of entry point */ ELF32_OFF PhOff; /* Program header table offset in file */ ELF32_OFF ShOff; /* Section header offset in file */ ELF32_WORD Flags; /* Processor specific flags - zero for SPARC and x86 */ ELF32_HALF EhSize; /* Elf header size in bytes (this struct) */ ELF32_HALF PhEntSize; /* Size of an entry in the program header table */ ELF32_HALF PhNum; /* Number of entries in the program header table */ ELF32_HALF ShEntSize; /* Size of an entry in the section header table */ ELF32_HALF ShNum; /* Number of entries in the section header table */ ELF32_HALF ShStrNdx; /* Index into the section header table for the entry of the section name string table */ } IMAGE_ELF32_HEADER, *PIMAGE_ELF32_HEADER;
/* Special section indexes */ #define IMAGE_ELF_SECTION_INDEX_UNDEF 0 /*#define IMAGE_ELF_SECTION_INDEX_LORESERVE 0xff00 #define IMAGE_ELF_SECTION_INDEX_LOPROC 0xff00 #define IMAGE_ELF_SECTION_INDEX_HIPROC 0xff1f*/ #define IMAGE_ELF_SECTION_INDEX_ABS 0xfff1 #define IMAGE_ELF_SECTION_INDEX_COMMON 0xfff2 /*#define IMAGE_ELF_SECTION_INDEX_HIRESERVE 0xffff*/
/* Section types */ #define IMAGE_ELF_SECTION_TYPE_NULL 0 /* Incactive section header */ #define IMAGE_ELF_SECTION_TYPE_PROGBITS 1 /* Program defined section */ #define IMAGE_ELF_SECTION_TYPE_SYMTAB 2 /* Symbol table (for link editing) */ #define IMAGE_ELF_SECTION_TYPE_STRTAB 3 /* String table */ #define IMAGE_ELF_SECTION_TYPE_RELA 4 /* Relocation table (with explicit addends) */ #define IMAGE_ELF_SECTION_TYPE_HASH 5 /* Symbol hash table */ #define IMAGE_ELF_SECTION_TYPE_DYNAMIC 6 /* Information for dynamic linking */ #define IMAGE_ELF_SECTION_TYPE_NOTE 7 /* Note section ;-) */ #define IMAGE_ELF_SECTION_TYPE_NOBITS 8 /* Occupies no space in the file, otherwise like PROGBITS */ #define IMAGE_ELF_SECTION_TYPE_REL 9 /* Relocation table (without explicit addends) */ #define IMAGE_ELF_SECTION_TYPE_SHLIB 10 /* Reserved, unspecified */ #define IMAGE_ELF_SECTION_TYPE_DYNSYM 11 /* Symbol table (for dynamic linking) */ /*#define IMAGE_ELF_SECTION_TYPE_LOPROC 0x70000000 #define IMAGE_ELF_SECTION_TYPE_HIPROC 0x7fffffff #define IMAGE_ELF_SECTION_TYPE_LOUSER 0x80000000 #define IMAGE_ELF_SECTION_TYPE_HIUSER 0xffffffff*/
/* Section flags/attributes */ #define SHF_WRITE 0x1 /* Section must be writeable */ #define SHF_ALLOC 0x2 /* Section must be loaded/mapped into memory */ #define SHF_EXECINSTR 0x4 /* The section contains executable code */ /*#define SHF_MASKPROC 0xf0000000*/
/* 32-bit Section header entry */ typedef struct _IMAGE_ELF32_SECTION_HEADER { ELF32_WORD Name; /* Name of the section (index into the section header string table) */ ELF32_WORD Type; /* Type of section */ ELF32_WORD Flags; /* Attributes */ ELF32_ADDR Addr; /* Virtual address to load section at */ ELF32_OFF Offset; /* Offset into the file of the section's data */ ELF32_WORD Size; /* Size of the section */ ELF32_WORD Link; /* Section header table index link... */ ELF32_WORD Info; /* Extra information... */ ELF32_WORD AddrAlign; /* Required alignment */ ELF32_WORD EntSize; /* Size of entries in the table */ } IMAGE_ELF32_SECTION_HEADER, *PIMAGE_ELF32_SECTION_HEADER;
/* Symbol table indexes */ #define IMAGE_ELF_SYMBOL_INDEX_UNDEF 0 /* Undefined symbol */
/* Symbol binding/types */ #define IMAGE_ELF32_SYMBOL_BIND(Info) ((Info) >> 4) #define IMAGE_ELF32_SYMBOL_TYPE(Info) ((Info) & 0x0f) #define IMAGE_ELF32_SYMBOL_INFO(Bind, Type) (((Bind) << 4) | ((Type) & 0x0f))
#define IMAGE_ELF_SYMBOL_BINDING_LOCAL 0 /* Local ("static") symbol */ #define IMAGE_ELF_SYMBOL_BINDING_GLOBAL 1 /* Global symbol */ #define IMAGE_ELF_SYMBOL_BINDING_WEAK 2 /* Weak symbol... */ /*#define IMAGE_ELF_SYMBOL_BINDING_LOPROC 13 #define IMAGE_ELF_SYMBOL_BINDING_HIPROC 15*/
#define IMAGE_ELF_SYMBOL_TYPE_NOTYPE 0 /* Unspecified symbol type */ #define IMAGE_ELF_SYMBOL_TYPE_OBJECT 1 /* Data object (i.e. an array, variable, ...) */ #define IMAGE_ELF_SYMBOL_TYPE_FUNC 2 /* Function (or other executable code) */ #define IMAGE_ELF_SYMBOL_TYPE_SECTION 3 /* Symbol for relocating (usually has local binding) */ #define IMAGE_ELF_SYMBOL_TYPE_FILE 4 /* Name of the associated source file */ #define IMAGE_ELF_SYMBOL_TYPE_LOPROC 13 #define IMAGE_ELF_SYMBOL_TYPE_HIPROC 15
/* 32-bit Symbol entry */ typedef struct _IMAGE_ELF32_SYMBOL { ELF32_WORD Name; /* Symbol name (index into the symbol string table) */ ELF32_ADDR Value; /* Value of symbol */ ELF32_WORD Size; /* Size of symbol (0 means unknown) */ unsigned char Info; /* Type and binding attributes */ unsigned char Other; /* Unused - 0 */ ELF32_HALF Shndx; /* Section index */ } IMAGE_ELF32_SYMBOL, *PIMAGE_ELF32_SYMBOL;
/* Relocation macros */ #define IMAGE_ELF32_RELOC_SYM(Info) ((Info) >> 8) #define IMAGE_ELF32_RELOC_TYPE(Info) ((unsigned char)(Info)) #define IMAGE_ELF32_RELOC_INFO(Sym,Type) (((Sym) << 8) | (unsigned char)(Type))
/* 386 Relocation types */ #define IMAGE_ELF_RELOC_386_NONE 0 /* none */ #define IMAGE_ELF_RELOC_386_32 1 #define IMAGE_ELF_RELOC_386_PC32 2 #define IMAGE_ELF_RELOC_386_GOT32 3 #define IMAGE_ELF_RELOC_386_PLT32 4 #define IMAGE_ELF_RELOC_386_COPY 5 #define IMAGE_ELF_RELOC_386_GLOB_DAT 6 #define IMAGE_ELF_RELOC_386_JMP_SLOT 7 #define IMAGE_ELF_RELOC_386_RELATIVE 8 #define IMAGE_ELF_RELOC_386_GOTOFF 9 #define IMAGE_ELF_RELOC_386_GOTPC 10
/* 386 TLS Relocation types */ #define IMAGE_ELF_RELOC_386_TLS_GD_PLT 12 #define IMAGE_ELF_RELOC_386_TLS_LDM_PLT 13 #define IMAGE_ELF_RELOC_386_TLS_TPOFF 14 #define IMAGE_ELF_RELOC_386_TLS_IE 15 #define IMAGE_ELF_RELOC_386_TLS_GOTIE 16 #define IMAGE_ELF_RELOC_386_TLS_LE 17 #define IMAGE_ELF_RELOC_386_TLS_GD 18 #define IMAGE_ELF_RELOC_386_TLS_LDM 19 #define IMAGE_ELF_RELOC_386_TLS_LDO_32 32 #define IMAGE_ELF_RELOC_386_TLS_DTPMOD32 35 #define IMAGE_ELF_RELOC_386_TLS_DTPOFF32 36
/* 32-bit Relocation entries */ typedef struct _IMAGE_ELF32_RELOC { ELF32_ADDR Offset; /* Section offset/virtual address */ ELF32_WORD Info; /* Symbol table index/relocation type */ } IMAGE_ELF32_RELOC, *PIMAGE_ELF32_RELOC;
typedef struct _IMAGE_ELF32_RELOCA { ELF32_ADDR Offset; /* Section offset/virtual address */ ELF32_WORD Info; /* Symbol table index/relocation type */ ELF32_SWORD Addend; /* Addend */ } IMAGE_ELF32_RELOCA, *PIMAGE_ELF32_RELOCA;
/* Program header/segment types */ #define IMAGE_ELF_SEGMENT_TYPE_NULL 0 /* Unused array entry */ #define IMAGE_ELF_SEGMENT_TYPE_LOAD 1 /* Loadable segment */ #define IMAGE_ELF_SEGMENT_TYPE_DYNAMIC 2 /* Dynamic linking info... */ #define IMAGE_ELF_SEGMENT_TYPE_INTERP 3 /* Interpreter */ #define IMAGE_ELF_SEGMENT_TYPE_NOTE 4 /* Note... */ #define IMAGE_ELF_SEGMENT_TYPE_SHLIB 5 /* Reserved but unspecified */ #define IMAGE_ELF_SEGMENT_TYPE_PHDR 6 /* Program header table */ #define IMAGE_ELF_SEGMENT_TYPE_TLS 7 /* Thread local storage */
#define IMAGE_ELF_SEGMENT_TYPE_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ #define IMAGE_ELF_SEGMENT_TYPE_GNU_STACK 0x6474e551 /* Indicates stack executability */ /*#define IMAGE_ELF_SEGMENT_TYPE_LOPROC 0x70000000 #define IMAGE_ELF_SEGMENT_TYPE_HIPROC 0x7fffffff*/
/* Program header/segment flags */ #define IMAGE_ELF_SEGMENT_FLAG_EXEC 0x01 #define IMAGE_ELF_SEGMENT_FLAG_WRITE 0x02 #define IMAGE_ELF_SEGMENT_FLAG_READ 0x04 /*#define IMAGE_ELF_SEGMENT_FLAG_MASKPROC 0xf0000000*/
/* 32-bit Program header entry */ typedef struct _IMAGE_ELF32_PROGRAM_HEADER { ELF32_WORD Type; /* Type of segment */ ELF32_OFF Offset; /* File offset of segment data */ ELF32_ADDR VAddr; /* Virtual address to load segment at */ ELF32_ADDR PAddr; /* Physical address to load segment at */ ELF32_WORD FileSz; /* Size in file of segment */ ELF32_WORD MemSz; /* Size in memory of segment */ ELF32_WORD Flags; /* Flags of segment */ ELF32_WORD Align; /* Required alignment */ } IMAGE_ELF32_PROGRAM_HEADER, *PIMAGE_ELF32_PROGRAM_HEADER;
/* Dynamic array tags */ #define IMAGE_ELF_DYNAMIC_TAG_NULL 0 /* End of array */ #define IMAGE_ELF_DYNAMIC_TAG_NEEDED 1 /* Dependency */ #define IMAGE_ELF_DYNAMIC_TAG_PLTRELSZ 2 /* Size in bytes of the relocation entries associated with the plt */ #define IMAGE_ELF_DYNAMIC_TAG_PLTGOT 3 /* Address associated with got/plt */ #define IMAGE_ELF_DYNAMIC_TAG_HASH 4 /* Hash table for symbol table indicated by SYMTAB */ #define IMAGE_ELF_DYNAMIC_TAG_STRTAB 5 /* Address of string table */ #define IMAGE_ELF_DYNAMIC_TAG_SYMTAB 6 /* Address of the symbol table */ #define IMAGE_ELF_DYNAMIC_TAG_RELA 7 /* Address of reloc table with addends */ #define IMAGE_ELF_DYNAMIC_TAG_RELASZ 8 /* Size of reloc table in bytes */ #define IMAGE_ELF_DYNAMIC_TAG_RELAENT 9 /* Size of reloc table entry in bytes? */ #define IMAGE_ELF_DYNAMIC_TAG_STRSZ 10 /* Size of the string table in bytes */ #define IMAGE_ELF_DYNAMIC_TAG_SYMENT 11 /* Size of symbol table entry in bytes */ #define IMAGE_ELF_DYNAMIC_TAG_INIT 12 /* Address of initialization function */ #define IMAGE_ELF_DYNAMIC_TAG_FINI 13 /* Address of termination function */ #define IMAGE_ELF_DYNAMIC_TAG_SONAME 14 /* Name of the shared object (string table offset) */ #define IMAGE_ELF_DYNAMIC_TAG_RPATH 15 /* Library search path (string table offset) */ #define IMAGE_ELF_DYNAMIC_TAG_SYMBOLIC 16 /* Alter runtime-linkers symbol resolution... */ #define IMAGE_ELF_DYNAMIC_TAG_REL 17 /* Address of reloc table without addends */ #define IMAGE_ELF_DYNAMIC_TAG_RELSZ 18 /* Size of reloc table in bytes */ #define IMAGE_ELF_DYNAMIC_TAG_RELENT 19 /* Size of reloc table entry in bytes? */ #define IMAGE_ELF_DYNAMIC_TAG_PLTREL 20 /* Type of relocation entry for plt (...TAG_REL or ...TAG_RELA) */ #define IMAGE_ELF_DYNAMIC_TAG_DEBUG 21 /* Used for debugging */ #define IMAGE_ELF_DYNAMIC_TAG_TEXTREL 22 /* If present informs the linker that a relocation might update a non-writable segment */ #define IMAGE_ELF_DYNAMIC_TAG_JMPREL 23 /* Address of relocation entries associated solely with the plt */ #define IMAGE_ELF_DYNAMIC_TAG_FILTER 24 /* Specifies the name of a shared objects for which this one acts as a filter */
#define IMAGE_ELF_DYNAMIC_TAG_RUNPATH 29 /* String table offset of a null-terminated library search path string. */ #define IMAGE_ELF_DYNAMIC_TAG_FLAGS 30 /* Object specific flag values. */
/* Dynamic flags (for IMAGE_ELF_DYNAMIC_TAG_FLAGS) */ #define IMAGE_ELF_DYNAMIC_FLAG_ORIGIN 0x0001 /* Indicates that the object being loaded may make reference to the $ORIGIN substitution string.*/ #define IMAGE_ELF_DYNAMIC_FLAG_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */ #define IMAGE_ELF_DYNAMIC_FLAG_TEXTREL 0x0004 /* Indicates there may be relocations in non-writable segments. */ #define IMAGE_ELF_DYNAMIC_FLAG_BIND_NOW 0x0008 /* Indicates that the dynamic linker should process all relocations for the object containing this entry before transferring control to the program. */ #define IMAGE_ELF_DYNAMIC_FLAG_STATIC_TLS 0x0010 /* Indicates that the shared object or executable contains code using a static thread-local storage scheme. */
/* Dynamic array entry */ typedef struct _IMAGE_ELF32_DYNAMIC { ELF32_SWORD Tag; union { ELF32_WORD Val; ELF32_ADDR Ptr; } Un; } IMAGE_ELF32_DYNAMIC, *PIMAGE_ELF32_DYNAMIC;
/* Auxiliary types */ #define IMAGE_ELF_AUX_TYPE_NULL 0 /* Terminates the vector. */ #define IMAGE_ELF_AUX_TYPE_IGNORE 1 /* Ignored entry. */ #define IMAGE_ELF_AUX_TYPE_EXECFD 2 /* File descriptor of program to load. */ #define IMAGE_ELF_AUX_TYPE_PHDR 3 /* Program header of program already loaded. */ #define IMAGE_ELF_AUX_TYPE_PHENT 4 /* Size of each program header entry. */ #define IMAGE_ELF_AUX_TYPE_PHNUM 5 /* Number of program header entries. */ #define IMAGE_ELF_AUX_TYPE_PAGESZ 6 /* Page size in bytes. */ #define IMAGE_ELF_AUX_TYPE_BASE 7 /* Interpreter's base address. */ #define IMAGE_ELF_AUX_TYPE_FLAGS 8 /* Flags (unused for i386). */ #define IMAGE_ELF_AUX_TYPE_ENTRY 9 /* Where interpreter should transfer control. */
/* * The following non-standard values are used for passing information * from John Polstra's testbed program to the dynamic linker. These * are expected to go away soon. * * Unfortunately, these overlap the Linux non-standard values, so they * must not be used in the same context. */ #define IMAGE_ELF_AUX_TYPE_BRK 10 /* Starting point for sbrk and brk. */ #define IMAGE_ELF_AUX_TYPE_DEBUG 11 /* Debugging level. */
/* * The following non-standard values are used in Linux ELF binaries. */ #define IMAGE_ELF_AUX_TYPE_NOTELF 10 /* Program is not ELF ?? */ #define IMAGE_ELF_AUX_TYPE_UID 11 /* Real uid. */ #define IMAGE_ELF_AUX_TYPE_EUID 12 /* Effective uid. */ #define IMAGE_ELF_AUX_TYPE_GID 13 /* Real gid. */ #define IMAGE_ELF_AUX_TYPE_EGID 14 /* Effective gid. */
#define IMAGE_ELF_AUX_TYPE_COUNT 15 /* Count of defined aux entry types. */
/* Auxiliary vector entry on initial stack */ typedef struct _IMAGE_ELF32_AUXINFO { ELF32_SWORD Type; /* Entry type. */ union { ELF32_SWORD Val; /* Integer value. */ ELF32_ADDR Ptr; /* Address. */ void (*Fcn)(void); /* Function pointer (not used). */ } Un; } IMAGE_ELF32_AUXINFO, *PIMAGE_ELF32_AUXINFO;
/* arch data types */
#if ELF_ARCH_SIZE == 32
#define IMAGE_ELF_SYMBOL_BIND(args...) IMAGE_ELF32_SYMBOL_BIND(args) #define IMAGE_ELF_SYMBOL_TYPE(args...) IMAGE_ELF32_SYMBOL_TYPE(args) #define IMAGE_ELF_SYMBOL_INFO(args...) IMAGE_ELF32_SYMBOL_INFO(args)
#define IMAGE_ELF_RELOC_SYM(args...) IMAGE_ELF32_RELOC_SYM(args) #define IMAGE_ELF_RELOC_TYPE(args...) IMAGE_ELF32_RELOC_TYPE(args) #define IMAGE_ELF_RELOC_INFO(args...) IMAGE_ELF32_RELOC_INFO(args)
typedef ELF32_ADDR ELF_ADDR; typedef ELF32_HALF ELF_HALF; typedef ELF32_OFF ELF_OFF; typedef ELF32_SWORD ELF_SWORD; typedef ELF32_WORD ELF_WORD; typedef ELF32_HASHELT ELF_HASHELT;
typedef IMAGE_ELF32_HEADER IMAGE_ELF_HEADER, *PIMAGE_ELF_HEADER; typedef IMAGE_ELF32_SECTION_HEADER IMAGE_ELF_SECTION_HEADER, *PIMAGE_ELF_SECTION_HEADER; typedef IMAGE_ELF32_SYMBOL IMAGE_ELF_SYMBOL, *PIMAGE_ELF_SYMBOL; typedef IMAGE_ELF32_RELOC IMAGE_ELF_RELOC, *PIMAGE_ELF_RELOC; typedef IMAGE_ELF32_RELOCA IMAGE_ELF_RELOCA, *PIMAGE_ELF_RELOCA; typedef IMAGE_ELF32_PROGRAM_HEADER IMAGE_ELF_PROGRAM_HEADER, *PIMAGE_ELF_PROGRAM_HEADER; typedef IMAGE_ELF32_DYNAMIC IMAGE_ELF_DYNAMIC, *PIMAGE_ELF_DYNAMIC; typedef IMAGE_ELF32_AUXINFO IMAGE_ELF_AUXINFO, *PIMAGE_ELF_AUXINFO;
#elif ELF_ARCH_SIZE == 64 # error 64 bits unsupported #else # error Undefined architecture size! #endif
/* target macros */ #ifdef _M_IX86 # define IMAGE_ELF_TARGET_CLASS IMAGE_ELF_CLASS_32 # define IMAGE_ELF_TARGET_DATA IMAGE_ELF_DATA_2LSB # define IMAGE_ELF_TARGET_MACHINE IMAGE_ELF_MACHINE_386 # define IMAGE_ELF_TARGET_VERSION 1 #else # error Unsupported architecture! #endif
#undef ELF_ARCH_SIZE
#endif /* __INCLUDE_ELF_H */
Index: ntoskrnl/mm/section.c =================================================================== RCS file: /CVS/ReactOS/reactos/ntoskrnl/mm/section.c,v retrieving revision 1.163 diff -u -r1.163 section.c --- ntoskrnl/mm/section.c 28 Sep 2004 20:58:29 -0000 1.163 +++ ntoskrnl/mm/section.c 19 Sep 2004 19:55:31 -0000 @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: section.c,v 1.163 2004/09/28 20:58:29 gvg Exp $ +/* $Id: section.c,v 1.162 2004/08/28 22:18:24 navaraf Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/section.c @@ -29,6 +29,8 @@ /* INCLUDES *****************************************************************/
#include <ntoskrnl.h> +#include <elf.h> + #define NDEBUG #include <internal/debug.h>
@@ -2506,6 +2508,18 @@ PAGE_EXECUTE_READWRITE, // 15 = WRITABLE, READABLE, EXECUTABLE, SHARED };
+static ULONG ElfProgramHeaderFlagsToProtect[8] = + { + PAGE_NOACCESS, /* 0 = NONE */ + PAGE_EXECUTE, /* 1 = EXECUTABLE */ + PAGE_READWRITE, /* 2 = WRITABLE */ + PAGE_EXECUTE_READWRITE, /* 3 = WRITABLE, EXECUTABLE */ + PAGE_READONLY, /* 4 = READABLE */ + PAGE_EXECUTE_READ, /* 5 = READABLE, EXECUTABLE */ + PAGE_READWRITE, /* 6 = READABLE, WRITABLE */ + PAGE_EXECUTE_READWRITE, /* 7 = READABLE, EXECUTABLE, WRITABLE */ + }; + NTSTATUS MmCreateImageSection(PSECTION_OBJECT *SectionObject, ACCESS_MASK DesiredAccess, @@ -2518,7 +2532,12 @@ PSECTION_OBJECT Section; NTSTATUS Status; PFILE_OBJECT FileObject; - IMAGE_DOS_HEADER DosHeader; + union { + IMAGE_DOS_HEADER DosHeader; +#ifdef _ELF_SUPPORT + IMAGE_ELF_HEADER ElfHeader; +#endif /* _ELF_SUPPORT */ + } FileHeader; IO_STATUS_BLOCK Iosb; LARGE_INTEGER Offset; IMAGE_NT_HEADERS PEHeader; @@ -2560,9 +2579,15 @@
if (!NT_SUCCESS(Status) || FileObject->SectionObjectPointer->ImageSectionObject == NULL) { - PIMAGE_SECTION_HEADER ImageSections; + PIMAGE_SECTION_HEADER ImageSections = NULL; +#ifdef _ELF_SUPPORT + PIMAGE_ELF_PROGRAM_HEADER ElfImagePHeaders = NULL; + BOOL ElfImageDynamic = FALSE; + PCHAR ElfImageInterp = NULL; +#endif + /* - * Read the dos header and check the DOS signature + * Read the DOS/ELF header and check the signature */ Offset.QuadPart = 0; Status = ZwReadFile(FileHandle, @@ -2570,8 +2595,8 @@ NULL, NULL, &Iosb, - &DosHeader, - sizeof(DosHeader), + &FileHeader, + sizeof(FileHeader), &Offset, NULL); if (!NT_SUCCESS(Status)) @@ -2581,78 +2606,357 @@ }
/* - * Check the DOS signature + * Check the DOS/ELF signature */ - if (Iosb.Information != sizeof(DosHeader) || - DosHeader.e_magic != IMAGE_DOS_SIGNATURE) + if (Iosb.Information != sizeof(FileHeader) || + (FileHeader.DosHeader.e_magic != IMAGE_DOS_SIGNATURE && +#ifdef _ELF_SUPPORT + !IMAGE_IS_ELF(FileHeader.ElfHeader))) +#else + TRUE)) +#endif { ObDereferenceObject(FileObject); return(STATUS_INVALID_IMAGE_FORMAT); }
- /* - * Read the PE header - */ - Offset.QuadPart = DosHeader.e_lfanew; - Status = ZwReadFile(FileHandle, - NULL, - NULL, - NULL, - &Iosb, - &PEHeader, - sizeof(PEHeader), - &Offset, - NULL); - if (!NT_SUCCESS(Status)) + if (FileHeader.DosHeader.e_magic == IMAGE_DOS_SIGNATURE) { - ObDereferenceObject(FileObject); - return(Status); - } - - /* - * Check the signature - */ - if (Iosb.Information != sizeof(PEHeader) || - PEHeader.Signature != IMAGE_NT_SIGNATURE) - { - ObDereferenceObject(FileObject); - return(STATUS_INVALID_IMAGE_FORMAT); - } + /* + * Read the PE header + */ + Offset.QuadPart = FileHeader.DosHeader.e_lfanew; + Status = ZwReadFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + &PEHeader, + sizeof(PEHeader), + &Offset, + NULL); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(FileObject); + return(Status); + }
- /* - * Read in the section headers - */ - Offset.QuadPart = DosHeader.e_lfanew + sizeof(PEHeader); - ImageSections = ExAllocatePool(NonPagedPool, - PEHeader.FileHeader.NumberOfSections * - sizeof(IMAGE_SECTION_HEADER)); - if (ImageSections == NULL) - { - ObDereferenceObject(FileObject); - return(STATUS_NO_MEMORY); - } + /* + * Check the signature + */ + if (Iosb.Information != sizeof(PEHeader) || + PEHeader.Signature != IMAGE_NT_SIGNATURE) + { + ObDereferenceObject(FileObject); + return(STATUS_INVALID_IMAGE_FORMAT); + }
- Status = ZwReadFile(FileHandle, - NULL, - NULL, - NULL, - &Iosb, - ImageSections, - PEHeader.FileHeader.NumberOfSections * - sizeof(IMAGE_SECTION_HEADER), - &Offset, - 0); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(FileObject); - ExFreePool(ImageSections); - return(Status); + /* + * Read in the section headers + */ + Offset.QuadPart = FileHeader.DosHeader.e_lfanew + sizeof(PEHeader); + ImageSections = ExAllocatePool(NonPagedPool, + PEHeader.FileHeader.NumberOfSections * + sizeof(IMAGE_SECTION_HEADER)); + if (ImageSections == NULL) + { + ObDereferenceObject(FileObject); + return(STATUS_NO_MEMORY); + } + + Status = ZwReadFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + ImageSections, + PEHeader.FileHeader.NumberOfSections * + sizeof(IMAGE_SECTION_HEADER), + &Offset, + 0); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(FileObject); + ExFreePool(ImageSections); + return(Status); + } + if (Iosb.Information != (PEHeader.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER))) + { + ObDereferenceObject(FileObject); + ExFreePool(ImageSections); + return(STATUS_INVALID_IMAGE_FORMAT); + } + NrSegments = PEHeader.FileHeader.NumberOfSections; } - if (Iosb.Information != (PEHeader.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER))) + else { - ObDereferenceObject(FileObject); - ExFreePool(ImageSections); - return(STATUS_INVALID_IMAGE_FORMAT); +#ifdef _ELF_SUPPORT + BOOL ElfImageOk = TRUE; + + assert(IMAGE_IS_ELF(FileHeader.ElfHeader)); + + /* + * Check the ELF type, target, ... + */ + if (FileHeader.ElfHeader.Ident[IMAGE_ELF_IDENT_CLASS] != IMAGE_ELF_TARGET_CLASS || + FileHeader.ElfHeader.Ident[IMAGE_ELF_IDENT_DATA] != IMAGE_ELF_TARGET_DATA) + { + DPRINT1("ELF: unsupported file layout\n"); + ElfImageOk = FALSE; + } + else if (FileHeader.ElfHeader.Ident[IMAGE_ELF_IDENT_VERSION] != IMAGE_ELF_VERSION_CURRENT || + FileHeader.ElfHeader.Version != IMAGE_ELF_VERSION_CURRENT) + { + DPRINT1("ELF: unsupported file version\n"); + ElfImageOk = FALSE; + } + else if (FileHeader.ElfHeader.Type != IMAGE_ELF_TYPE_EXEC && + FileHeader.ElfHeader.Type != IMAGE_ELF_TYPE_DYN) + { + DPRINT1("ELF: unsupported file type\n"); + ElfImageOk = FALSE; + } + else if (FileHeader.ElfHeader.Machine != IMAGE_ELF_TARGET_MACHINE) + { + DPRINT1("ELF: unsupported machine\n"); + ElfImageOk = FALSE; + } + else if (FileHeader.ElfHeader.PhEntSize != sizeof(IMAGE_ELF_PROGRAM_HEADER)) + { + DPRINT1("ELF: invalid object: ElfHeader.PhEntSize != sizeof(IMAGE_ELF_PROGRAM_HEADER)\n"); + ElfImageOk = FALSE; + } + else if (FileHeader.ElfHeader.PhOff == 0) + { + DPRINT1("ELF: file does not contain a program header table (PhOff == 0)\n"); + ElfImageOk = FALSE; + } + else if (FileHeader.ElfHeader.PhNum == 0) + { + DPRINT1("ELF: file does not contain a program header table (PhNum == 0)\n"); + ElfImageOk = FALSE; + } + + if (!ElfImageOk) + { + ObDereferenceObject(FileObject); + return(STATUS_INVALID_IMAGE_FORMAT); + } + + /* + * Read in the program header table + */ + Offset.QuadPart = FileHeader.ElfHeader.PhOff; + ElfImagePHeaders = ExAllocatePool(NonPagedPool, + FileHeader.ElfHeader.PhNum * + sizeof(IMAGE_ELF_PROGRAM_HEADER)); + if (ElfImagePHeaders == NULL) + { + ObDereferenceObject(FileObject); + return(STATUS_NO_MEMORY); + } + + Status = ZwReadFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + ElfImagePHeaders, + FileHeader.ElfHeader.PhNum * + sizeof(IMAGE_ELF_PROGRAM_HEADER), + &Offset, + 0); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(FileObject); + ExFreePool(ElfImagePHeaders); + return(Status); + } + if (Iosb.Information != (FileHeader.ElfHeader.PhNum * sizeof(IMAGE_ELF_PROGRAM_HEADER))) + { + ObDereferenceObject(FileObject); + ExFreePool(ElfImagePHeaders); + return(STATUS_INVALID_IMAGE_FORMAT); + } + + /* + * Get some important program headers (.dynamic, .interp), count number of loadable segments + */ + NrSegments = 0; + for (i = 0; i < FileHeader.ElfHeader.PhNum; i++) + { + switch (ElfImagePHeaders[i].Type) + { + case IMAGE_ELF_SEGMENT_TYPE_NULL: + case IMAGE_ELF_SEGMENT_TYPE_PHDR: + break; + + case IMAGE_ELF_SEGMENT_TYPE_LOAD: + /* Check alignment of segment */ + if (ElfImagePHeaders[i].Align > 1 && ElfImagePHeaders[i].Align < PAGE_SIZE) + { + ObDereferenceObject(FileObject); + ExFreePool(ElfImagePHeaders); + if (ElfImageInterp != NULL) + ExFreePool(ElfImageInterp); + + DPRINT1("ELF: IMAGE_ELF_SEGMENT_TYPE_LOAD Segment %d not page-aligned\n", i); + return(STATUS_INVALID_IMAGE_FORMAT); + } + NrSegments++; + break; + + case IMAGE_ELF_SEGMENT_TYPE_DYNAMIC: /* dynamically linked image */ + ElfImageDynamic = TRUE; + break; + + case IMAGE_ELF_SEGMENT_TYPE_INTERP: + /* Allocate memory for interpreter */ + if (ElfImageInterp != NULL) + { + ObDereferenceObject(FileObject); + ExFreePool(ElfImagePHeaders); + ExFreePool(ElfImageInterp); + DPRINT1("ELF: Only one IMAGE_ELF_SEGMENT_TYPE_INTERP segment allowed\n"); + return(STATUS_INVALID_IMAGE_FORMAT); + } + Size = max(ElfImagePHeaders[i].MemSz, ElfImagePHeaders[i].FileSz + 1); + ElfImageInterp = ExAllocatePool(NonPagedPool, Size); + if (ElfImageInterp == NULL) + { + ObDereferenceObject(FileObject); + ExFreePool(ElfImagePHeaders); + return(STATUS_NO_MEMORY); + } + + /* Read interpreter path */ + Offset.QuadPart = ElfImagePHeaders[i].Offset; + Status = ZwReadFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + ElfImageInterp, + ElfImagePHeaders[i].FileSz, + &Offset, + 0); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(FileObject); + ExFreePool(ElfImagePHeaders); + ExFreePool(ElfImageInterp); + return(Status); + } + if (Iosb.Information != ElfImagePHeaders[i].FileSz) + { + ObDereferenceObject(FileObject); + ExFreePool(ElfImagePHeaders); + ExFreePool(ElfImageInterp); + return(STATUS_INVALID_IMAGE_FORMAT); + } + ElfImageInterp[Size - 1] = '\0'; + break; + +#if 0 + case IMAGE_ELF_SEGMENT_TYPE_GNU_STACK: + ElfImageStackExec = TRUE; /* Stack should be executable */ + break; +#endif + default: /* Unknown/unused type */ + DPRINT1("ELF: Segment %d has unknown type %d\n", i, ElfImagePHeaders[i].Type); + break; + } + } + + if (NrSegments == 0) /* No loadable segments found */ + { + ObDereferenceObject(FileObject); + ExFreePool(ElfImagePHeaders); + if (ElfImageInterp != NULL) + ExFreePool(ElfImageInterp); + DPRINT1("ELF: No loadable segments found!\n"); + return(STATUS_INVALID_IMAGE_FORMAT); + } + + if (ElfImageDynamic) + { + HANDLE hInterpFile; + OBJECT_ATTRIBUTES Attribs; + ANSI_STRING AnsiInterp; + UNICODE_STRING UnicodeInterp; + + if(ElfImageInterp == NULL) + { + ObDereferenceObject(FileObject); + ExFreePool(ElfImagePHeaders); + DPRINT1("ELF: Dynamic image needs interpreter!\n"); + return(STATUS_INVALID_IMAGE_FORMAT); + } + + /* + * Release resources + */ + ObDereferenceObject(FileObject); + ExFreePool(ElfImagePHeaders); + + /* + * The ELF file contains an interpreter, let's try to map it instead... + */ + RtlInitAnsiString(&AnsiInterp, ElfImageInterp); + Status = RtlAnsiStringToUnicodeString(&UnicodeInterp, &AnsiInterp, TRUE); + ExFreePool(ElfImageInterp); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ELF: Couldn't convert interpreter from ansi to unicode!\n"); + return(Status); + } + + InitializeObjectAttributes(&Attribs, + &UnicodeInterp, + (OBJ_CASE_INSENSITIVE | OBJ_INHERIT), /* FIXME: which flags to use? */ + NULL, + NULL); + + Status = ZwCreateFile(&hInterpFile, + GENERIC_READ | GENERIC_EXECUTE, + &Attribs, + &Iosb, + NULL, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ, + FILE_OPEN, + FILE_NON_DIRECTORY_FILE, + NULL, + 0); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("ELF: Couldn't open interpreter '%wZ'!\n", &UnicodeInterp); + RtlFreeUnicodeString(&UnicodeInterp); + return(Status); + } + RtlFreeUnicodeString(&UnicodeInterp); + + Status = MmCreateImageSection(SectionObject, + DesiredAccess, + NULL, + NULL, + PAGE_EXECUTE | PAGE_WRITECOPY, + SEC_IMAGE, + hInterpFile); + ZwClose(hInterpFile); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ELF: Couldn't create section for interpreter (0x%x)\n", Status); + } + return(Status); /* The interpreter should take care of the rest... */ + } + + NrSegments = FileHeader.ElfHeader.PhNum; + +#else /* _ELF_SUPPORT */ + assert(0); /* should never be executed */ +#endif }
/* @@ -2670,7 +2974,14 @@ if (!NT_SUCCESS(Status)) { ObDereferenceObject(FileObject); - ExFreePool(ImageSections); + if (ImageSections != NULL) + ExFreePool(ImageSections); +#ifdef _ELF_SUPPORT + if (ElfImagePHeaders != NULL) + ExFreePool(ElfImagePHeaders); + if (ElfImageInterp != NULL) + ExFreePool(ElfImageInterp); +#endif return(Status); }
@@ -2684,8 +2995,8 @@ KeInitializeSpinLock(&Section->ViewListLock);
/* - * Check file access required - */ + * Check file access required + */ if (SectionPageProtection & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE)) { FileAccess = FILE_READ_DATA | FILE_WRITE_DATA; @@ -2703,14 +3014,21 @@ { ObDereferenceObject(Section); ObDereferenceObject(FileObject); - ExFreePool(ImageSections); + if (ImageSections != NULL) + ExFreePool(ImageSections); +#ifdef _ELF_SUPPORT + if (ElfImagePHeaders != NULL) + ExFreePool(ElfImagePHeaders); + if (ElfImageInterp != NULL) + ExFreePool(ElfImageInterp); +#endif return(Status); }
/* - * allocate the section segments to describe the mapping + * allocate and fill the section segments to describe the mapping */ - NrSegments = PEHeader.FileHeader.NumberOfSections + 1; + NrSegments += 1; /* the first segment is special i guess... */ Size = sizeof(MM_IMAGE_SECTION_OBJECT) + sizeof(MM_SECTION_SEGMENT) * NrSegments; ImageSectionObject = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_MM_SECTION_SEGMENT); if (ImageSectionObject == NULL) @@ -2718,110 +3036,241 @@ KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); ObDereferenceObject(Section); ObDereferenceObject(FileObject); - ExFreePool(ImageSections); + if (ImageSections != NULL) + ExFreePool(ImageSections); +#ifdef _ELF_SUPPORT + if (ElfImagePHeaders != NULL) + ExFreePool(ElfImagePHeaders); + if (ElfImageInterp != NULL) + ExFreePool(ElfImageInterp); +#endif return(STATUS_NO_MEMORY); } Section->ImageSection = ImageSectionObject; ImageSectionObject->NrSegments = NrSegments; - ImageSectionObject->ImageBase = (PVOID)PEHeader.OptionalHeader.ImageBase; - ImageSectionObject->EntryPoint = (PVOID)PEHeader.OptionalHeader.AddressOfEntryPoint; - ImageSectionObject->StackReserve = PEHeader.OptionalHeader.SizeOfStackReserve; - ImageSectionObject->StackCommit = PEHeader.OptionalHeader.SizeOfStackCommit; - ImageSectionObject->Subsystem = PEHeader.OptionalHeader.Subsystem; - ImageSectionObject->MinorSubsystemVersion = PEHeader.OptionalHeader.MinorSubsystemVersion; - ImageSectionObject->MajorSubsystemVersion = PEHeader.OptionalHeader.MajorSubsystemVersion; - ImageSectionObject->ImageCharacteristics = PEHeader.FileHeader.Characteristics; - ImageSectionObject->Machine = PEHeader.FileHeader.Machine; - ImageSectionObject->Executable = (PEHeader.OptionalHeader.SizeOfCode != 0); - SectionSegments = ImageSectionObject->Segments; - SectionSegments[0].FileOffset = 0; - SectionSegments[0].Characteristics = IMAGE_SECTION_CHAR_DATA; - SectionSegments[0].Protection = PAGE_READONLY; - SectionSegments[0].RawLength = PAGE_SIZE; - SectionSegments[0].Length = PAGE_SIZE; - SectionSegments[0].Flags = 0; - SectionSegments[0].ReferenceCount = 1; - SectionSegments[0].VirtualAddress = 0; - SectionSegments[0].WriteCopy = TRUE; - SectionSegments[0].Attributes = 0; - ExInitializeFastMutex(&SectionSegments[0].Lock); - RtlZeroMemory(&SectionSegments[0].PageDirectory, sizeof(SECTION_PAGE_DIRECTORY)); - for (i = 1; i < NrSegments; i++) - { - SectionSegments[i].FileOffset = ImageSections[i-1].PointerToRawData; - SectionSegments[i].Characteristics = ImageSections[i-1].Characteristics;
- /* - * Set up the protection and write copy variables. - */ - Characteristics = ImageSections[i - 1].Characteristics; - if (Characteristics & (IMAGE_SECTION_CHAR_READABLE|IMAGE_SECTION_CHAR_WRITABLE|IMAGE_SECTION_CHAR_EXECUTABLE)) - { - SectionSegments[i].Protection = SectionCharacteristicsToProtect[Characteristics >> 28]; - SectionSegments[i].WriteCopy = !(Characteristics & IMAGE_SECTION_CHAR_SHARED); - } - else if (Characteristics & IMAGE_SECTION_CHAR_CODE) - { - SectionSegments[i].Protection = PAGE_EXECUTE_READ; - SectionSegments[i].WriteCopy = TRUE; - } - else if (Characteristics & IMAGE_SECTION_CHAR_DATA) - { - SectionSegments[i].Protection = PAGE_READWRITE; - SectionSegments[i].WriteCopy = TRUE; - } - else if (Characteristics & IMAGE_SECTION_CHAR_BSS) - { - SectionSegments[i].Protection = PAGE_READWRITE; - SectionSegments[i].WriteCopy = TRUE; - } - else + if (FileHeader.DosHeader.e_magic == IMAGE_DOS_SIGNATURE) + { + ImageSectionObject->ImageBase = (PVOID)PEHeader.OptionalHeader.ImageBase; + ImageSectionObject->EntryPoint = (PVOID)PEHeader.OptionalHeader.AddressOfEntryPoint; + ImageSectionObject->StackReserve = PEHeader.OptionalHeader.SizeOfStackReserve; + ImageSectionObject->StackCommit = PEHeader.OptionalHeader.SizeOfStackCommit; + ImageSectionObject->Subsystem = PEHeader.OptionalHeader.Subsystem; + ImageSectionObject->MinorSubsystemVersion = PEHeader.OptionalHeader.MinorSubsystemVersion; + ImageSectionObject->MajorSubsystemVersion = PEHeader.OptionalHeader.MajorSubsystemVersion; + ImageSectionObject->ImageCharacteristics = PEHeader.FileHeader.Characteristics; + ImageSectionObject->Machine = PEHeader.FileHeader.Machine; + ImageSectionObject->Executable = (PEHeader.OptionalHeader.SizeOfCode != 0); + + SectionSegments[0].FileOffset = 0; + SectionSegments[0].Characteristics = IMAGE_SECTION_CHAR_DATA; + SectionSegments[0].Protection = PAGE_READONLY; + SectionSegments[0].RawLength = PAGE_SIZE; + SectionSegments[0].Length = PAGE_SIZE; + SectionSegments[0].Flags = 0; + SectionSegments[0].ReferenceCount = 1; + SectionSegments[0].VirtualAddress = 0; + SectionSegments[0].WriteCopy = TRUE; + SectionSegments[0].Attributes = 0; + ExInitializeFastMutex(&SectionSegments[0].Lock); + RtlZeroMemory(&SectionSegments[0].PageDirectory, sizeof(SECTION_PAGE_DIRECTORY)); + for (i = 1; i < NrSegments; i++) { - SectionSegments[i].Protection = PAGE_NOACCESS; - SectionSegments[i].WriteCopy = TRUE; - } + SectionSegments[i].FileOffset = ImageSections[i-1].PointerToRawData; + SectionSegments[i].Characteristics = ImageSections[i-1].Characteristics;
- /* - * Set up the attributes. - */ - if (Characteristics & IMAGE_SECTION_CHAR_CODE) - { - SectionSegments[i].Attributes = 0; + /* + * Set up the protection and write copy variables. + */ + Characteristics = ImageSections[i - 1].Characteristics; + if (Characteristics & (IMAGE_SECTION_CHAR_READABLE|IMAGE_SECTION_CHAR_WRITABLE|IMAGE_SECTION_CHAR_EXECUTABLE)) + { + SectionSegments[i].Protection = SectionCharacteristicsToProtect[Characteristics >> 28]; + SectionSegments[i].WriteCopy = !(Characteristics & IMAGE_SECTION_CHAR_SHARED); + } + else if (Characteristics & IMAGE_SECTION_CHAR_CODE) + { + SectionSegments[i].Protection = PAGE_EXECUTE_READ; + SectionSegments[i].WriteCopy = TRUE; + } + else if (Characteristics & IMAGE_SECTION_CHAR_DATA) + { + SectionSegments[i].Protection = PAGE_READWRITE; + SectionSegments[i].WriteCopy = TRUE; + } + else if (Characteristics & IMAGE_SECTION_CHAR_BSS) + { + SectionSegments[i].Protection = PAGE_READWRITE; + SectionSegments[i].WriteCopy = TRUE; + } + else + { + SectionSegments[i].Protection = PAGE_NOACCESS; + SectionSegments[i].WriteCopy = TRUE; + } + + /* + * Set up the attributes. + */ + if (Characteristics & IMAGE_SECTION_CHAR_CODE) + { + SectionSegments[i].Attributes = 0; + } + else if (Characteristics & IMAGE_SECTION_CHAR_DATA) + { + SectionSegments[i].Attributes = 0; + } + else if (Characteristics & IMAGE_SECTION_CHAR_BSS) + { + SectionSegments[i].Attributes = MM_SECTION_SEGMENT_BSS; + } + else + { + SectionSegments[i].Attributes = 0; + } + + SectionSegments[i].RawLength = ImageSections[i-1].SizeOfRawData; + if (ImageSections[i-1].Misc.VirtualSize != 0) + { + SectionSegments[i].Length = ImageSections[i-1].Misc.VirtualSize; + } + else + { + SectionSegments[i].Length = ImageSections[i-1].SizeOfRawData; + } + SectionSegments[i].Flags = 0; + SectionSegments[i].ReferenceCount = 1; + SectionSegments[i].VirtualAddress = (PVOID)ImageSections[i-1].VirtualAddress; + ExInitializeFastMutex(&SectionSegments[i].Lock); + RtlZeroMemory(&SectionSegments[i].PageDirectory, sizeof(SECTION_PAGE_DIRECTORY)); } - else if (Characteristics & IMAGE_SECTION_CHAR_DATA) + } + else + { +#ifdef _ELF_SUPPORT + ULONG j; + + ImageSectionObject->ImageBase = (PVOID)ElfImagePHeaders[0].VAddr; + ImageSectionObject->EntryPoint = (PVOID)FileHeader.ElfHeader.Entry; + if (FileHeader.ElfHeader.Entry != (ELF_ADDR)NULL) + { + ImageSectionObject->EntryPoint = (PVOID)((UINT_PTR)FileHeader.ElfHeader.Entry - + (UINT_PTR)ImageSectionObject->ImageBase); + } + ImageSectionObject->StackReserve = 0x10000; /* FIXME: does ELF provide such info? */ + ImageSectionObject->StackCommit = 0x1000; /* FIXME: does ELF provide such info? */ + ImageSectionObject->Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; /* FIXME: we need to extend ELF */ + ImageSectionObject->MajorSubsystemVersion = 4; + ImageSectionObject->MinorSubsystemVersion = 0; /* WinNT 4.0 */ + ImageSectionObject->Executable = TRUE; + ImageSectionObject->ImageCharacteristics = IMAGE_FILE_32BIT_MACHINE; + if (FileHeader.ElfHeader.Type == IMAGE_ELF_TYPE_EXEC) { - SectionSegments[i].Attributes = 0; + ImageSectionObject->ImageCharacteristics |= IMAGE_FILE_EXECUTABLE_IMAGE; } - else if (Characteristics & IMAGE_SECTION_CHAR_BSS) + else { - SectionSegments[i].Attributes = MM_SECTION_SEGMENT_BSS; - } + assert(FileHeader.ElfHeader.Type == IMAGE_ELF_TYPE_DYN); + ImageSectionObject->ImageCharacteristics |= IMAGE_FILE_DLL; + } + + if (FileHeader.ElfHeader.Machine == IMAGE_ELF_MACHINE_386) + ImageSectionObject->Machine = IMAGE_FILE_MACHINE_I386; else { - SectionSegments[i].Attributes = 0; + /* + * This should never be reached because we check if + * ElfHeader.Machine is IMAGE_ELF_TARGET_MACHINE above + * and fail if it is not. + */ + assert(0); }
- SectionSegments[i].RawLength = ImageSections[i-1].SizeOfRawData; - if (ImageSections[i-1].Misc.VirtualSize != 0) + /* FIXME: what is this first segment used for? */ + SectionSegments[0].FileOffset = 0; + SectionSegments[0].Characteristics = IMAGE_SECTION_CHAR_DATA; + SectionSegments[0].Protection = PAGE_READONLY; + SectionSegments[0].RawLength = PAGE_SIZE; + SectionSegments[0].Length = PAGE_SIZE; + SectionSegments[0].Flags = 0; + SectionSegments[0].ReferenceCount = 1; + SectionSegments[0].VirtualAddress = 0; + SectionSegments[0].WriteCopy = TRUE; + SectionSegments[0].Attributes = 0; + ExInitializeFastMutex(&SectionSegments[0].Lock); + RtlZeroMemory(&SectionSegments[0].PageDirectory, sizeof(SECTION_PAGE_DIRECTORY)); + for (i = 1, j = 0; j < (NrSegments - 1); j++) { - SectionSegments[i].Length = ImageSections[i-1].Misc.VirtualSize; - } - else - { - SectionSegments[i].Length = ImageSections[i-1].SizeOfRawData; - } - SectionSegments[i].Flags = 0; - SectionSegments[i].ReferenceCount = 1; - SectionSegments[i].VirtualAddress = (PVOID)ImageSections[i-1].VirtualAddress; - ExInitializeFastMutex(&SectionSegments[i].Lock); - RtlZeroMemory(&SectionSegments[i].PageDirectory, sizeof(SECTION_PAGE_DIRECTORY)); + if (ElfImagePHeaders[j].Type != IMAGE_ELF_SEGMENT_TYPE_LOAD) + continue; + + SectionSegments[i].FileOffset = ElfImagePHeaders[j].Offset; + + /* + * Fill in characteristics + */ + Characteristics = 0; + if (ElfImagePHeaders[j].Flags & IMAGE_ELF_SEGMENT_FLAG_READ) + Characteristics |= IMAGE_SECTION_CHAR_READABLE; + if (ElfImagePHeaders[j].Flags & IMAGE_ELF_SEGMENT_FLAG_WRITE) + Characteristics |= IMAGE_SECTION_CHAR_WRITABLE; + if (ElfImagePHeaders[j].Flags & IMAGE_ELF_SEGMENT_FLAG_EXEC) + Characteristics |= IMAGE_SECTION_CHAR_EXECUTABLE | IMAGE_SECTION_CHAR_CODE; + else /* not executable, must be some kind of data */ + Characteristics |= (ElfImagePHeaders[j].FileSz > 0) ? IMAGE_SECTION_CHAR_DATA : + IMAGE_SECTION_CHAR_BSS; + SectionSegments[i].Characteristics = Characteristics; + + /* + * Set up the protection and write copy variables. + */ + SectionSegments[i].Protection = ElfProgramHeaderFlagsToProtect[ElfImagePHeaders[j].Flags & 7]; + SectionSegments[i].WriteCopy = TRUE; /* ELF does not support shared segments */ + + /* + * Set up the attributes. + */ + if (Characteristics & IMAGE_SECTION_CHAR_CODE) + { + SectionSegments[i].Attributes = 0; + } + else if (Characteristics & IMAGE_SECTION_CHAR_DATA) + { + SectionSegments[i].Attributes = 0; + } + else if (Characteristics & IMAGE_SECTION_CHAR_BSS) + { + SectionSegments[i].Attributes = MM_SECTION_SEGMENT_BSS; + } + else + { + SectionSegments[i].Attributes = 0; + } + + SectionSegments[i].RawLength = ElfImagePHeaders[j].FileSz; + SectionSegments[i].Length = ElfImagePHeaders[j].MemSz; /* FIXME: I hope these are correct */ + + SectionSegments[i].Flags = 0; + SectionSegments[i].ReferenceCount = 1; + SectionSegments[i].VirtualAddress = (PVOID)((UINT_PTR)ElfImagePHeaders[j].VAddr - + (UINT_PTR)ImageSectionObject->ImageBase); + ExInitializeFastMutex(&SectionSegments[i].Lock); + RtlZeroMemory(&SectionSegments[i].PageDirectory, sizeof(SECTION_PAGE_DIRECTORY)); + + i++; + } + ImageSectionObject->NrSegments = i; + +#else /* if !_ELF_SUPPORT */ + assert(0); +#endif /* !_ELF_SUPPORT */ } if (0 != InterlockedCompareExchange((PLONG)&FileObject->SectionObjectPointer->ImageSectionObject, (LONG)ImageSectionObject, 0)) { /* - * An other thread has initialized the some image in the background + * An other thread has initialized the same image in the background */ ExFreePool(ImageSectionObject); ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject; @@ -2833,7 +3282,10 @@ InterlockedIncrement((LONG *)&SectionSegments[i].ReferenceCount); } } - ExFreePool(ImageSections); + if (ImageSections != NULL) + ExFreePool(ImageSections); + if (ElfImagePHeaders != NULL) + ExFreePool(ElfImagePHeaders); } else { @@ -3809,7 +4261,7 @@ return(STATUS_UNSUCCESSFUL); } /* Otherwise find a gap to map the image. */ - ImageBase = MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize), PAGE_SIZE, FALSE); + ImageBase = MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize), FALSE); if (ImageBase == NULL) { MmUnlockAddressSpace(AddressSpace);