[ros-dev] ELF mapping support for ntoskrnl, for anybody who is interested (untested)

Gregor Anich blight at blight.eu.org
Thu Nov 25 13:57:03 CET 2004


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
-------------- next part --------------
#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 */

-------------- next part --------------
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);


More information about the Ros-dev mailing list