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);
At 13.57 25/11/2004, you wrote:
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.
I'll try to commit this into a branch. I have a couple of Wine binaries I can test
We also have to port a runtime linker (rtld)
I doubt we'll need this. I'll try to add support for querying the interpreter name, but I don't think we really need this for Win32. POSIX maybe (hence a way to query an ELF image section for the interpreter name), but for Win32 I think we're stretching it enough at supporting ELF at all. Then again I don't really know what runtime linkers are for
Hi,
--- "KJK::Hyperion" noog@libero.it wrote:
I'll try to commit this into a branch. I have a couple of Wine binaries I can test
Let me know of any way I can help on this.
Thanks Steven
__________________________________ Do you Yahoo!? The all-new My Yahoo! - Get yours free! http://my.yahoo.com
On Thu, 25 Nov 2004 12:00:24 -0800 (PST) Steven Edwards steven_ed4153@yahoo.com wrote:
Hi,
--- "KJK::Hyperion" noog@libero.it wrote:
I'll try to commit this into a branch. I have a couple of Wine binaries I can test
Let me know of any way I can help on this.
Thanks Steven
Please post a tutorial (or link) on building elf exes.
Hi,
--- art yerkes ayerkes@speakeasy.net wrote:
Please post a tutorial (or link) on building elf exes.
Building a Win32 winelib application is well documented here
http://www.winehq.com/site/winelib
In short if you are lucky and if your project already builds with Mingw converting it to be a winelib application can be only a few minutes work. Winelib uses the winebuild tool that we already have in ReactOS as well as another tool called winegcc which is a wrapper around gcc on Unix to make it act like Mingw.
My hope is that by adding ELF support to ReactOS we will make porting ReactOS almost as easy as it is to port Winelib to another platform. Right now Winelib runs on MacOS/X, LinuxPPC, Solaris/Linux on Sparc and a Alpha port is under way.
Thanks Steven
__________________________________ Do you Yahoo!? All your favorites on one personal page � Try My Yahoo! http://my.yahoo.com
Hello,
I am impressed, because it is not easy to write a ELF runtime link editor, and more difficult to build a ELF to COFF conversor on the fly...
I am working with ELF at low level from six months ago and it is not an easy task, because there are not too much tutorials about ELF... only specs and some articles...
My recommended bookmarks are:
- The System V ABI Specification (ELF Specs). A "must read" if you plan to do anything with ELF http://www.caldera.com/developers/devspecs/ http://www.caldera.com/developers/gabi/
- How to use dl_open interface. It is not part of ELF specs, but it's found in any modern Un*x. http://docsrv.sco.com:8457/en/DevelopLib/dl-libraries.html
- A Phrack article talking about using ELFsh and manipulating ELF files. http://www.phrack.org/show.php?p=61&a=8
- The Linux GCC Howto. Explains some details about dynamic loading. http://www.linuxdocs.org/HOWTOs/GCC-HOWTO/
- ELFsh. The ELF shell is an interactive, modular and scriptable ELF (Executable & Linking Format) machine designed for executable files, shared libraries and relocatable ELF objects manipulation. Interesting source code. http://elfsh.segfault.net/
- The LSB. Explains some details about ELF on Linux. If you are planning to support ELF you must deal with the same ELF format of Linux. http://www.linuxbase.org/spec/
- One of the most important: Tool Interface Standard (TIS) Executable and Linking Format (ELF) Specification: http://www.x86.org/ftp/manuals/tools/elf.pdf
- This is very interesting. It shows what is important in the ELF headers: http://www.comms.scitech.susx.ac.uk/fft/programming/teensy.html
Luck! Gerardo García Peña
art yerkes wrote:
Please post a tutorial (or link) on building elf exes.
Ah! I forgot...
two things: - sorry for my bad english... I know it is horrible... - if you have any question about ELF format, dynamic linking, etc... please: ask me, I will try to do my best :P
Gerardo García
art yerkes wrote:
Please post a tutorial (or link) on building elf exes.
KJK::Hyperion wrote:
I doubt we'll need this. I'll try to add support for querying the interpreter name, but I don't think we really need this for Win32. POSIX maybe (hence a way to query an ELF image section for the interpreter name), but for Win32 I think we're stretching it enough at supporting ELF at all. Then again I don't really know what runtime linkers are for
Hi, is the ELF "interpreter name" what in PE images is the subsystem field?
On Saturday 27 November 2004 11:46, Aliberti Emanuele wrote:
KJK::Hyperion wrote:
I doubt we'll need this. I'll try to add support for querying the interpreter name, but I don't think we really need this for Win32. POSIX maybe (hence a way to query an ELF image section for the interpreter name), but for Win32 I think we're stretching it enough at supporting ELF at all. Then again I don't really know what runtime linkers are for
Hi, is the ELF "interpreter name" what in PE images is the subsystem field?
I don't know the "subsystem field", but I doubt it. The interpreter tells what the kernel should use to "interpret" the image. When an ELF file is loaded it is mapped into memory, then the kernel looks if there is an interpreter (a filename like /lib/ld-linux.so.2) and if there is one it also maps the interpreter file into memory and starts execution at the interpreter's entry point instead of the executable image to be loaded. The interpreter (rtld - runtime link editor) relocates itself and the executable image, sets up other stuff and transfers execution to the executable image's entry point. On windows (for PE files) ntdll is doing that.
At 11.46 27/11/2004, you wrote:
I doubt we'll need this. I'll try to add support for querying the interpreter name, but I don't think we really need this for Win32. POSIX maybe (hence a way to query an ELF image section for the interpreter name), but for Win32 I think we're stretching it enough at supporting ELF at all. Then again I don't really know what runtime linkers are for
Hi, is the ELF "interpreter name" what in PE images is the subsystem field?
nope, various fields in the executable's header are analyzed heuristically to determine the OS it was compiled for. There is an "ABI" field in the ELF header for this, IIRC, but it's not used consistently, hence the heuristics. You can read more about this in a series of technical articles about NetBSD on the O'Reilly network:
http://www.onlamp.com/pub/a/bsd/2002/08/08/irix.html?page=2 (last section) http://www.onlamp.com/pub/a/onlamp/2001/05/10/linux_bsd.html?page=4
Many interesting things about ELF, including program loading and interpreter stuff loading can be found here:
http://www.x86.org/ftp/manuals/tools/elf.pdf
Emil
Quoting "KJK::Hyperion" noog@libero.it:
At 11.46 27/11/2004, you wrote:
I doubt we'll need this. I'll try to add support for querying the interpreter name, but I don't think we really need this for Win32. POSIX maybe (hence a way to query an ELF image section for the interpreter name), but for Win32 I think we're stretching it enough at supporting ELF at all. Then again I don't really know what runtime linkers are for
Hi, is the ELF "interpreter name" what in PE images is the subsystem field?
nope, various fields in the executable's header are analyzed heuristically to determine the OS it was compiled for. There is an "ABI" field in the ELF header for this, IIRC, but it's not used consistently, hence the heuristics. You can read more about this in a series of technical articles about NetBSD on the O'Reilly network:
http://www.onlamp.com/pub/a/bsd/2002/08/08/irix.html?page=2 (last section) http://www.onlamp.com/pub/a/onlamp/2001/05/10/linux_bsd.html?page=4
Ros-dev mailing list Ros-dev@reactos.com http://reactos.com:8080/mailman/listinfo/ros-dev
Another interesting paper is "ELF Handling For Thread-Local Storage" - http://people.redhat.com/drepper/tls.pdf
emild@cs.technion.ac.il wrote:
Many interesting things about ELF, including program loading and interpreter stuff loading can be found here:
And more: Userland Exec (usermode ELF loader) http://www.mail-archive.com/full-disclosure%40lists.netsys.com/msg12548.html
Gregor Anich wrote:
Another interesting paper is "ELF Handling For Thread-Local Storage" - http://people.redhat.com/drepper/tls.pdf
emild@cs.technion.ac.il wrote:
Many interesting things about ELF, including program loading and interpreter stuff loading can be found here: