From c6b57fbd1aa2e6cecf2e3f0277417e367abf3699 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Sat, 1 Nov 2008 01:25:51 +0000 Subject: [PATCH] PE loader. link with required dll git-svn-id: svn://kolibrios.org@892 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/branches/kolibri_pe/build.bat | 105 --- kernel/branches/kolibri_pe/core/dll.c | 710 +++------------------ kernel/branches/kolibri_pe/core/export.asm | 18 +- kernel/branches/kolibri_pe/core/heap.c | 86 +-- kernel/branches/kolibri_pe/core/pe.c | 414 ++++++++++++ kernel/branches/kolibri_pe/include/mm.h | 1 + kernel/branches/kolibri_pe/include/pe.h | 202 ++++++ kernel/branches/kolibri_pe/kernel.asm | 5 +- kernel/branches/kolibri_pe/make.sh | 33 - kernel/branches/kolibri_pe/makefile | 1 + 10 files changed, 753 insertions(+), 822 deletions(-) delete mode 100644 kernel/branches/kolibri_pe/build.bat create mode 100644 kernel/branches/kolibri_pe/core/pe.c create mode 100644 kernel/branches/kolibri_pe/include/pe.h delete mode 100755 kernel/branches/kolibri_pe/make.sh diff --git a/kernel/branches/kolibri_pe/build.bat b/kernel/branches/kolibri_pe/build.bat deleted file mode 100644 index becb36ebb..000000000 --- a/kernel/branches/kolibri_pe/build.bat +++ /dev/null @@ -1,105 +0,0 @@ -@echo off - -set languages=en ru ge et -set drivers=sound sis infinity ensoniq ps2mouse com_mouse uart ati2d vmode -set targets=all kernel drivers skins clean - -call :Check_Target %1 -for %%a in (all kernel) do if %%a==%target% call :Check_Lang %2 -call :Target_%target% - -if ERRORLEVEL 0 goto Exit_OK - -echo There was an error executing script. -echo For any help, please send a report. -pause -goto :eof - - - - -:Check_Lang - set res=%1 - :Check_Lang_loop - for %%a in (%languages%) do if %%a==%res% set lang=%res% - if defined lang goto :eof - - echo Language '%res%' is incorrect - echo Enter valid language [ %languages% ]: - - set /P res="> - goto Check_Lang_loop -goto :eof - -:Check_Target - set res=%1 - :Check_Target_loop - for %%a in (%targets%) do if %%a==%res% set target=%res% - if defined target goto :eof - - echo Target '%res%' is incorrect - echo Enter valid target [ %targets% ]: - - set /P res="> - goto Check_Target_loop -goto :eof - - -:Target_kernel - echo *** building kernel with language '%lang%' ... - - if not exist bin mkdir bin - echo lang fix %lang% > lang.inc - fasm -m 65536 kernel.asm bin\kernel.mnt - if not %errorlevel%==0 goto :Error_FasmFailed - erase lang.inc -goto :eof - - -:Target_all - call :Target_kernel - call :Target_drivers - call :Target_skins -goto :eof - - -:Target_drivers - echo *** building drivers ... - - if not exist bin\drivers mkdir bin\drivers - cd drivers - for %%a in (%drivers%) do ( - fasm -m 65536 %%a.asm ..\bin\drivers\%%a.obj - if not %errorlevel%==0 goto :Error_FasmFailed - ) - cd .. - move bin\drivers\vmode.obj bin\drivers\vmode.mdr -goto :eof - - -:Target_skins - echo *** building skins ... - - if not exist bin\skins mkdir bin\skins - cd skin - fasm -m 65536 default.asm ..\bin\skins\default.skn - if not %errorlevel%==0 goto :Error_FasmFailed - cd .. -goto :eof - -:Target_clean - echo *** cleaning ... - rmdir /S /Q bin -goto :Exit_OK - - -:Error_FasmFailed -echo error: fasm execution failed -erase lang.inc -pause -exit 1 - -:Exit_OK -echo all operations has been done -pause -exit 0 diff --git a/kernel/branches/kolibri_pe/core/dll.c b/kernel/branches/kolibri_pe/core/dll.c index 56235f245..ce0655bf0 100644 --- a/kernel/branches/kolibri_pe/core/dll.c +++ b/kernel/branches/kolibri_pe/core/dll.c @@ -5,244 +5,75 @@ #include #include #include - -typedef unsigned short WORD; -typedef unsigned int DWORD; -typedef unsigned int LONG; -typedef unsigned char BYTE; - -#define IMAGE_DOS_SIGNATURE 0x5A4D -#define IMAGE_NT_SIGNATURE 0x00004550 -#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b - -#pragma pack(push,2) -typedef struct _IMAGE_DOS_HEADER -{ - WORD e_magic; - WORD e_cblp; - WORD e_cp; - WORD e_crlc; - WORD e_cparhdr; - WORD e_minalloc; - WORD e_maxalloc; - WORD e_ss; - WORD e_sp; - WORD e_csum; - WORD e_ip; - WORD e_cs; - WORD e_lfarlc; - WORD e_ovno; - WORD e_res[4]; - WORD e_oemid; - WORD e_oeminfo; - WORD e_res2[10]; - LONG e_lfanew; -} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER; -#pragma pack(pop) - - -#pragma pack(push,4) -typedef struct _IMAGE_FILE_HEADER -{ - WORD Machine; - WORD NumberOfSections; - DWORD TimeDateStamp; - DWORD PointerToSymbolTable; - DWORD NumberOfSymbols; - WORD SizeOfOptionalHeader; - WORD Characteristics; -} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; - -typedef struct _IMAGE_DATA_DIRECTORY { - DWORD VirtualAddress; - DWORD Size; -} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY; - -#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 - -typedef struct _IMAGE_OPTIONAL_HEADER { - WORD Magic; - BYTE MajorLinkerVersion; - BYTE MinorLinkerVersion; - DWORD SizeOfCode; - DWORD SizeOfInitializedData; - DWORD SizeOfUninitializedData; - DWORD AddressOfEntryPoint; - DWORD BaseOfCode; - DWORD BaseOfData; - DWORD ImageBase; - DWORD SectionAlignment; - DWORD FileAlignment; - WORD MajorOperatingSystemVersion; - WORD MinorOperatingSystemVersion; - WORD MajorImageVersion; - WORD MinorImageVersion; - WORD MajorSubsystemVersion; - WORD MinorSubsystemVersion; - DWORD Win32VersionValue; - DWORD SizeOfImage; - DWORD SizeOfHeaders; - DWORD CheckSum; - WORD Subsystem; - WORD DllCharacteristics; - DWORD SizeOfStackReserve; - DWORD SizeOfStackCommit; - DWORD SizeOfHeapReserve; - DWORD SizeOfHeapCommit; - DWORD LoaderFlags; - DWORD NumberOfRvaAndSizes; - IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; -} IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER; - -#pragma pack(pop) - - -#pragma pack(push,4) -typedef struct _IMAGE_NT_HEADERS -{ - DWORD Signature; - IMAGE_FILE_HEADER FileHeader; - IMAGE_OPTIONAL_HEADER OptionalHeader; -} IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32; - -#define IMAGE_SIZEOF_SHORT_NAME 8 - -typedef struct _IMAGE_SECTION_HEADER -{ - BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; - union - { - DWORD PhysicalAddress; - DWORD VirtualSize; - } Misc; - DWORD VirtualAddress; - DWORD SizeOfRawData; - DWORD PointerToRawData; - DWORD PointerToRelocations; - DWORD PointerToLinenumbers; - WORD NumberOfRelocations; - WORD NumberOfLinenumbers; - DWORD Characteristics; -} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER; -#pragma pack(pop) - -#pragma pack(push,4) -typedef struct _IMAGE_BASE_RELOCATION { - DWORD VirtualAddress; - DWORD SizeOfBlock; -} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION; -#pragma pack(pop) - -typedef struct _IMAGE_IMPORT_DESCRIPTOR -{ - union - { - DWORD Characteristics; - DWORD OriginalFirstThunk; - }; - DWORD TimeDateStamp; - DWORD ForwarderChain; - DWORD Name; - DWORD FirstThunk; -} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR; - -typedef struct _IMAGE_THUNK_DATA32 -{ - union - { - DWORD ForwarderString; - DWORD Function; - DWORD Ordinal; - DWORD AddressOfData; - } u1; -} IMAGE_THUNK_DATA32,*PIMAGE_THUNK_DATA32; - -typedef struct _IMAGE_IMPORT_BY_NAME -{ - WORD Hint; - BYTE Name[1]; -} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME; - -#define IMAGE_ORDINAL_FLAG 0x80000000 - -typedef struct _IMAGE_EXPORT_DIRECTORY { - DWORD Characteristics; - DWORD TimeDateStamp; - WORD MajorVersion; - WORD MinorVersion; - DWORD Name; - DWORD Base; - DWORD NumberOfFunctions; - DWORD NumberOfNames; - DWORD AddressOfFunctions; - DWORD AddressOfNames; - DWORD AddressOfNameOrdinals; -} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY; - -//extern IMAGE_EXPORT_DIRECTORY kernel_exports; - -#define MakePtr( cast, ptr, addValue ) (cast)( (addr_t)(ptr) + (addValue) ) - -typedef struct -{ - addr_t base; - addr_t frame; - md_t *md; - - IMAGE_OPTIONAL_HEADER *opthdr; - -}dll_t; - -static inline bool IsPowerOf2(u32_t val) -{ - if(val == 0) - return false; - return (val & (val - 1)) == 0; -} - - -static inline void sec_copy(void *dst, const void *src, size_t len) -{ - u32_t tmp; - __asm__ __volatile__ ( - "shrl $2, %%ecx \n\t" - "rep movsl" - :"=c"(tmp),"=S"(tmp),"=D"(tmp) - :"c"(len),"S"(src),"D"(dst) - :"cc"); -}; - -static inline void sec_clear(void *dst, size_t len) -{ - u32_t tmp; - __asm__ __volatile__ ( - "xorl %%eax, %%eax \n\t" - "rep stosb" - :"=c"(tmp),"=D"(tmp) - :"c"(len),"D"(dst) - :"eax","cc"); -}; +#include int __stdcall strncmp(const char *s1, const char *s2, size_t n); +static dll_t core_dll; -void __export create_image(void *img_base, void *image) asm ("CreateImage"); - -md_t* __fastcall load_image(const char *path); - - -void* __fastcall load_pe(const char *path) +static char* strupr(char *str ) { - md_t *md; + char *p; + unsigned char c; - md = load_image(path); + p = str; + while( (c = *p) ) + { + if( c >= 'a' && c <= 'z' ) + *p = c - 'a' + 'A'; + ++p; + } - if( md ) - return (void*)md->base; + return( str ); +} + +void init_core_dll() +{ + PIMAGE_DOS_HEADER dos; + PIMAGE_NT_HEADERS32 nt; + PIMAGE_EXPORT_DIRECTORY exp; + + dos = (PIMAGE_DOS_HEADER)LOAD_BASE; + nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); + exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE, + nt->OptionalHeader.DataDirectory[0].VirtualAddress); + + list_initialize(&core_dll.link); + + core_dll.img_base = LOAD_BASE; + core_dll.img_size = nt->OptionalHeader.SizeOfImage; + core_dll.img_md = NULL; + + core_dll.img_hdr = nt; + core_dll.img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32)); + core_dll.img_exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE, + nt->OptionalHeader.DataDirectory[0].VirtualAddress); + core_dll.img_name = strupr(MakePtr(char*, LOAD_BASE, exp->Name)); + + DBG("%s base %x size %x sections %d exports %x\n", + core_dll.img_name, core_dll.img_base, + core_dll.img_size, nt->FileHeader.NumberOfSections, + core_dll.img_exp ); +}; + + +dll_t * find_dll(const char *name) +{ + dll_t* dll = &core_dll; + + do + { + if( !strncmp(name,dll->img_name,16)) + return dll; + + dll = (dll_t*)dll->link.next; + + }while(&dll->link != &core_dll.link); return NULL; }; + typedef struct { char srv_name[16]; // ASCIIZ string @@ -271,418 +102,25 @@ srv_t* __fastcall load_pe_driver(const char *path) if( ! md ) return 0; - dos = (PIMAGE_DOS_HEADER)md->base; - nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); + if( link_image( md->base ) ) + { + dos = (PIMAGE_DOS_HEADER)md->base; + nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); - drv_entry = MakePtr(drv_entry_t*, md->base, - nt->OptionalHeader.AddressOfEntryPoint); + drv_entry = MakePtr(drv_entry_t*, md->base, + nt->OptionalHeader.AddressOfEntryPoint); - srv = drv_entry(1); + srv = drv_entry(1); - if(srv != NULL) - srv->entry = nt->OptionalHeader.AddressOfEntryPoint + md->base; + if(srv != NULL) + srv->entry = nt->OptionalHeader.AddressOfEntryPoint + md->base; - return srv; + return srv; + } + else + { + md_free( md ); + return NULL; + } } -md_t* __fastcall load_image(const char *path) -{ - PIMAGE_DOS_HEADER dos; - PIMAGE_NT_HEADERS32 nt; - - md_t *img_md; - - size_t img_size; - void *img_base; - count_t img_pages; - - size_t raw_size = 0; - void *raw; - -// void *image; - - DBG("load file %s\n", path); - - raw = load_file(path, &raw_size); - - DBG("raw = %x\n\n", raw); - - dos = (PIMAGE_DOS_HEADER)raw; - - if( !raw || raw_size < sizeof(IMAGE_DOS_HEADER) ) - return NULL; - - if( dos->e_magic != IMAGE_DOS_SIGNATURE || dos->e_lfanew <= 0) - return NULL; - - nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); - - if( (addr_t)nt < (addr_t)raw) - return NULL; - - if(nt->Signature != IMAGE_NT_SIGNATURE) - return NULL; - - if(nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) - return NULL; - - if(nt->OptionalHeader.SectionAlignment < PAGE_SIZE) - { - if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment) - return NULL; - } - else if(nt->OptionalHeader.SectionAlignment < nt->OptionalHeader.FileAlignment) - return NULL; - - if(!IsPowerOf2(nt->OptionalHeader.SectionAlignment) || - !IsPowerOf2(nt->OptionalHeader.FileAlignment)) - return NULL; - - if(nt->FileHeader.NumberOfSections > 96) - return NULL; - - img_size = nt->OptionalHeader.SizeOfImage; -// img_pages = img_size / PAGE_SIZE; - - img_md = md_alloc(img_size, PG_SW); - - - if( !img_md) - { - mem_free(raw); - return NULL; - }; - - img_base = (void*)img_md->base; - - create_image(img_base, raw); - - mem_free(raw); - -// dos = (PIMAGE_DOS_HEADER)img_base; -// nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); - - return img_md; -}; - - -/* -addr_t get_proc_addr(addr_t module, char *name) -{ - PIMAGE_DOS_HEADER expdos; - PIMAGE_NT_HEADERS32 expnt; - PIMAGE_EXPORT_DIRECTORY exp; - u32_t *functions; - char **funcname; - int ind; - - expdos = (PIMAGE_DOS_HEADER)module; - expnt = MakePtr( PIMAGE_NT_HEADERS32, expdos, expdos->e_lfanew); - - exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,module, - expnt->OptionalHeader.DataDirectory[0].VirtualAddress); - - functions = MakePtr(DWORD*,exp->AddressOfFunctions,module); - funcname = MakePtr(char**,exp->AddressOfNames,module); - - for(ind=0; *funcname;funcname++,ind++) - { - if(!strcmp(name,MakePtr(char*,*funcname,module))) - return functions[ind] + module; - }; - return -1; -}; -*/ - - -void create_image(void *img_base, void *image) -{ - PIMAGE_DOS_HEADER dos; - PIMAGE_NT_HEADERS32 nt; - PIMAGE_SECTION_HEADER img_sec; - - u32_t sec_align; - int i; - - -/* assumed that image is valid */ - - dos = (PIMAGE_DOS_HEADER)image; - nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); - - sec_copy(img_base,image,nt->OptionalHeader.SizeOfHeaders); - - img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt,sizeof(IMAGE_NT_HEADERS32)); - - sec_align = nt->OptionalHeader.SectionAlignment; - - for(i=0; i< nt->FileHeader.NumberOfSections; i++) - { - char *src_ptr; - char *dest_ptr; - size_t sec_size; - - src_ptr = MakePtr(char*, image, img_sec->PointerToRawData); - dest_ptr = MakePtr(char*,img_base, img_sec->VirtualAddress); - - if(img_sec->SizeOfRawData) - sec_copy(dest_ptr, src_ptr, img_sec->SizeOfRawData); - - sec_size = (img_sec->Misc.VirtualSize + sec_align -1) & -sec_align; - - if(sec_size > img_sec->SizeOfRawData) - sec_clear(dest_ptr + img_sec->SizeOfRawData, - sec_size - img_sec->SizeOfRawData); - img_sec++; - } - - if(nt->OptionalHeader.DataDirectory[5].Size) - { - PIMAGE_BASE_RELOCATION reloc; - -/* FIXME addr_t */ - - u32_t delta = (u32_t)img_base - nt->OptionalHeader.ImageBase; - - reloc = MakePtr(PIMAGE_BASE_RELOCATION, img_base, - nt->OptionalHeader.DataDirectory[5].VirtualAddress); - - while ( reloc->SizeOfBlock != 0 ) - { - u32_t cnt; - u16_t *entry; - u16_t reltype; - u32_t offs; - - cnt = (reloc->SizeOfBlock - sizeof(*reloc))/sizeof(u16_t); - entry = MakePtr( u16_t*, reloc, sizeof(*reloc) ); - - for ( i=0; i < cnt; i++ ) - { - u16_t *p16; - u32_t *p32; - - reltype = (*entry & 0xF000) >> 12; - offs = (*entry & 0x0FFF) + reloc->VirtualAddress; - switch(reltype) - { - case 1: - p16 = MakePtr(u16_t*, img_base, offs); - *p16+= (u16_t)(delta>>16); - break; - case 2: - p16 = MakePtr(u16_t*, img_base, offs); - *p16+= (u16_t)delta; - break; - case 3: - p32 = MakePtr(u32_t*, img_base, offs); - *p32+= delta; - } - entry++; - } - reloc = MakePtr(PIMAGE_BASE_RELOCATION, reloc,reloc->SizeOfBlock); - } - }; - - if(nt->OptionalHeader.DataDirectory[1].Size) - { - PIMAGE_IMPORT_DESCRIPTOR imp; - - int warn = 0; - - imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, img_base, - nt->OptionalHeader.DataDirectory[1].VirtualAddress); - - - - while ( 1 ) - { - PIMAGE_THUNK_DATA32 thunk; - - PIMAGE_DOS_HEADER expdos; - PIMAGE_NT_HEADERS32 expnt; - PIMAGE_EXPORT_DIRECTORY exp; - - u32_t *iat; - char *libname; - addr_t *functions; - u16_t *ordinals; - char **funcname; - - - if ( (imp->TimeDateStamp==0 ) && (imp->Name==0) ) - break; - - libname=MakePtr(char*,imp->Name, img_base); - - DBG("import from %s\n",libname); - - expdos = (PIMAGE_DOS_HEADER)IMAGE_BASE; - expnt = MakePtr( PIMAGE_NT_HEADERS32, expdos, expdos->e_lfanew); - - exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE, - expnt->OptionalHeader.DataDirectory[0].VirtualAddress); - - functions = MakePtr(DWORD*,exp->AddressOfFunctions,LOAD_BASE); - ordinals = MakePtr(WORD*, exp->AddressOfNameOrdinals,LOAD_BASE); - funcname = MakePtr(char**, exp->AddressOfNames,LOAD_BASE); - - thunk = MakePtr(PIMAGE_THUNK_DATA32, - imp->Characteristics, img_base); - iat= MakePtr(DWORD*,imp->FirstThunk, img_base); - - while ( 1 ) // Loop forever (or until we break out) - { - PIMAGE_IMPORT_BY_NAME ord; - addr_t addr; - - if ( thunk->u1.AddressOfData == 0 ) - break; - - if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG ) - { - // printf(" %4u\n", thunk->u1.Ordinal & 0xFFFF); - break; - } - else - { - ord = MakePtr(PIMAGE_IMPORT_BY_NAME, - thunk->u1.AddressOfData, img_base); - *iat=0; - - DBG("import %s", ord->Name); - - if(strncmp(ord->Name, - MakePtr(char*,funcname[ord->Hint],LOAD_BASE),32)) - { - int ind; - char **names=funcname; - - for(names = funcname,ind = 0; - ind < exp->NumberOfNames; names++,ind++) - { - if(!strncmp(ord->Name,MakePtr(char*,*names,LOAD_BASE),32)) - { - DBG(" \tat %x\n", functions[ind] + LOAD_BASE); - *iat = functions[ind] + LOAD_BASE; - break; - }; - }; - if(ind == exp->NumberOfNames) - { - DBG(" unresolved import %s\n",ord->Name); - warn=1; - }; - } - else - { - DBG(" \tat %x\n", functions[ord->Hint] + LOAD_BASE); - *iat = functions[ord->Hint] + LOAD_BASE; - }; - }; - thunk++; // Advance to next thunk - iat++; - } - imp++; // advance to next IMAGE_IMPORT_DESCRIPTOR - }; - }; - - DBG("\ncreate pe base %x, size %x, %d sections\n\n",img_base, - nt->OptionalHeader.SizeOfImage, nt->FileHeader.NumberOfSections); -}; - - - - - -/* - -u32 map_PE(u32 base, void *image) -{ - PIMAGE_DOS_HEADER dos; - PIMAGE_NT_HEADERS32 nt; - PIMAGE_SECTION_HEADER sec; - - int i; - int pages; - - dos = (PIMAGE_DOS_HEADER)image; - nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); - - - img_size = nt->OptionalHeader.SizeOfImage; - img_pages = img_size / PAGE_SIZE; - - img_md = md_alloc(img_size, PG_SW); - - if( !img_md) - return NULL; - - - - scopy(base,(u32)image,nt->OptionalHeader.SizeOfHeaders); - - sec = MakePtr(PIMAGE_SECTION_HEADER,nt,sizeof(IMAGE_NT_HEADERS32)); - - - if(nt->OptionalHeader.DataDirectory[1].Size) - { - PIMAGE_IMPORT_DESCRIPTOR imp; - - imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR,base, - nt->OptionalHeader.DataDirectory[1].VirtualAddress); - while ( 1 ) - { - PIMAGE_THUNK_DATA32 thunk; - u32 *iat; - char *libname; - - if ( (imp->TimeDateStamp==0 ) && (imp->Name==0) ) - break; - - - thunk = MakePtr(PIMAGE_THUNK_DATA32, - imp->Characteristics, base); - iat= MakePtr(DWORD*,imp->FirstThunk, base); - - while ( 1 ) // Loop forever (or until we break out) - { - PIMAGE_IMPORT_BY_NAME ord; - - u32 addr; - - if ( thunk->u1.AddressOfData == 0 ) - break; - - if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG ) - { - // printf(" %4u\n", thunk->u1.Ordinal & 0xFFFF); - break; - } - else - { - PKERNEL_EXPORT exp; - exp = kernel_export; - - ord = MakePtr(PIMAGE_IMPORT_BY_NAME, - thunk->u1.AddressOfData,base); - *iat=-1; - - do - { - if(!strncmp(ord->Name,exp->name,16)) - { - *iat = exp->address; - break; - } - exp++; - } while(exp->name != 0); - }; - thunk++; // Advance to next thunk - iat++; - } - imp++; // advance to next IMAGE_IMPORT_DESCRIPTOR - } - }; - -*/ diff --git a/kernel/branches/kolibri_pe/core/export.asm b/kernel/branches/kolibri_pe/core/export.asm index 69e096d2c..d05e479cd 100644 --- a/kernel/branches/kolibri_pe/core/export.asm +++ b/kernel/branches/kolibri_pe/core/export.asm @@ -3,24 +3,24 @@ .section .drectve - .ascii " -export:CreateImage" - .ascii " -export:LoadFile" + .ascii " -export:CreateImage" # cdecl + .ascii " -export:LoadFile" # stdcall - .ascii " -export:Kmalloc" # - .ascii " -export:Kfree" # + .ascii " -export:Kmalloc" # eax FIXME + .ascii " -export:Kfree" # eax FIXME .ascii " -export:UserAlloc" # stdcall .ascii " -export:UserFree" # stdcall + .ascii " -export:GetPgAddr" # eax FIXME .ascii " -export:MapIoMem" # stdcall - .ascii " -export:GetPgAddr" # eax - .ascii " -export:CreateObject" # - .ascii " -export:DestroyObject" # .ascii " -export:CreateRingBuffer" # stdcall - .ascii " -export:CommitPages" # eax, ebx, ecx + .ascii " -export:CommitPages" # eax, ebx, ecx FIXME + .ascii " -export:UnmapPages" # eax, ecx FIXME + .ascii " -export:CreateObject" # eax, ebx FIXME + .ascii " -export:DestroyObject" # eax .ascii " -export:RegService" # stdcall - .ascii " -export:UnmapPages" # eax, ecx .ascii " -export:SysMsgBoardStr" # .ascii " -export:SetScreen" # diff --git a/kernel/branches/kolibri_pe/core/heap.c b/kernel/branches/kolibri_pe/core/heap.c index da8cf6b0f..844bc63d4 100644 --- a/kernel/branches/kolibri_pe/core/heap.c +++ b/kernel/branches/kolibri_pe/core/heap.c @@ -110,7 +110,7 @@ md_t* __fastcall find_large_md(size_t size) if(idx0 == 31) { md_t *tmp = (md_t*)lheap.unmapped[31].next; - while((link_t*)tmp != &lheap.unmapped[31]) + while(&tmp->link != &lheap.unmapped[31]) { if(tmp->size >= size) { @@ -193,7 +193,7 @@ md_t* __fastcall find_unmapped_md(size_t size) ASSERT( !list_empty(&sheap.unmapped[31])); md_t *tmp = (md_t*)sheap.unmapped[31].next; - while((link_t*)tmp != &sheap.unmapped[31]) + while( &tmp->link != &sheap.unmapped[31]) { if(tmp->size >= size) { @@ -283,7 +283,7 @@ md_t* __fastcall find_unmapped_md(size_t size) { md_t *tmp = (md_t*)sheap.unmapped[31].next; - while((link_t*)tmp != &sheap.unmapped[31]) + while( &tmp->link != &sheap.unmapped[31]) { if(md->base < tmp->base) break; @@ -333,7 +333,7 @@ md_t* __fastcall find_mapped_md(size_t size) ASSERT( !list_empty(&sheap.mapped[31])); md_t *tmp = (md_t*)sheap.mapped[31].next; - while((link_t*)tmp != &sheap.mapped[31]) + while( &tmp->link != &sheap.mapped[31]) { if(tmp->size >= size) { @@ -437,7 +437,7 @@ md_t* __fastcall find_mapped_md(size_t size) { md_t *tmp = (md_t*)sheap.mapped[31].next; - while((link_t*)tmp != &sheap.mapped[31]) + while( &tmp->link != &sheap.mapped[31]) { if(md->base < tmp->base) break; @@ -521,7 +521,7 @@ void __fastcall free_unmapped_md(md_t *md) { md_t *tmp = (md_t*)sheap.unmapped[31].next; - while((link_t*)tmp != &sheap.unmapped[31]) + while( &tmp->link != &sheap.unmapped[31]) { if(md->base < tmp->base) break; @@ -598,7 +598,7 @@ void __fastcall free_mapped_md(md_t *md) { md_t *tmp = (md_t*)sheap.mapped[31].next; - while((link_t*)tmp != &sheap.mapped[31]) + while( &tmp->link != &sheap.mapped[31]) { if(md->base < tmp->base) break; @@ -663,6 +663,44 @@ md_t* __fastcall md_alloc(size_t size, u32_t flags) }; +void __fastcall md_free(md_t *md) +{ + + if( md ) + { + md_t *lmd; + + DBG("free md: %x base: %x size: %x\n",md, md->base, md->size); + + ASSERT(md->state == MD_USED); + + list_remove((link_t*)md); + + lmd = (md_t*)md->parent; + + ASSERT(lmd != 0); + + if(lmd->parent != 0) + { + addr_t mem = md->base; + addr_t *pte = &((addr_t*)page_tabs)[md->base>>12]; + count_t tmp = md->size >> 12; + + while(tmp--) + { + *pte++ = 0; + asm volatile ( "invlpg (%0)" ::"r" (mem) ); + mem+= 4096; + }; + free_mapped_md( md ); + } + else + free_unmapped_md( md ); + } + + return; +}; + void * __fastcall mem_alloc(size_t size, u32_t flags) { eflags_t efl; @@ -687,7 +725,7 @@ void * __fastcall mem_alloc(size_t size, u32_t flags) { md_t *tmp = (md_t*)sheap.used.next; - while((link_t*)tmp != &sheap.used) + while( &tmp->link != &sheap.used) { if(md->base < tmp->base) break; @@ -720,7 +758,7 @@ void __fastcall mem_free(void *mem) tmp = (md_t*)sheap.used.next; - while((link_t*)tmp != &sheap.used) + while( &tmp->link != &sheap.used) { if( tmp->base == (addr_t)mem ) { @@ -732,36 +770,8 @@ void __fastcall mem_free(void *mem) if( md ) { - md_t *lmd; + md_free( md ); - DBG("\tmd: %x base: %x size: %x\n",md, md->base, md->size); - - ASSERT(md->state == MD_USED); - - list_remove((link_t*)md); - - lmd = (md_t*)md->parent; - - ASSERT(lmd != 0); - - if(lmd->parent != 0) - { - count_t tmp = md->size >> 12; - addr_t *pte = &((addr_t*)page_tabs)[md->base>>12]; - - while(tmp--) - { - *pte++ = 0; - asm volatile ( - "invlpg (%0)" - ::"r" (mem) ); - mem+= 4096; - }; - - free_mapped_md( md ); - } - else - free_unmapped_md( md ); } else DBG("\tERROR: invalid base address: %x\n", mem); diff --git a/kernel/branches/kolibri_pe/core/pe.c b/kernel/branches/kolibri_pe/core/pe.c new file mode 100644 index 000000000..ea705c38d --- /dev/null +++ b/kernel/branches/kolibri_pe/core/pe.c @@ -0,0 +1,414 @@ + +#include +#include +#include +#include +#include +#include +#include + + +static inline bool IsPowerOf2(u32_t val) +{ + if(val == 0) + return false; + return (val & (val - 1)) == 0; +} + + +static inline void sec_copy(addr_t dst, addr_t src, size_t len) +{ + u32_t tmp; + __asm__ __volatile__ ( + "shrl $2, %%ecx \n\t" + "rep movsl" + :"=c"(tmp),"=S"(tmp),"=D"(tmp) + :"c"(len),"S"(src),"D"(dst) + :"cc"); +}; + +static inline void sec_clear(addr_t dst, size_t len) +{ + u32_t tmp; + __asm__ __volatile__ ( + "xorl %%eax, %%eax \n\t" + "rep stosb" + :"=c"(tmp),"=D"(tmp) + :"c"(len),"D"(dst) + :"eax","cc"); +}; + +int __stdcall strncmp(const char *s1, const char *s2, size_t n); + +void __export create_image(addr_t img_base, addr_t raw) asm ("CreateImage"); +bool link_image(addr_t img_base); + +md_t* __fastcall load_image(const char *path); + +/* +void* __fastcall load_pe(const char *path) +{ + md_t *md; + + md = load_image(path); + + if( md ) + return (void*)md->base; + + return NULL; +}; +*/ + +bool validate_pe(void *raw, size_t raw_size) +{ + PIMAGE_DOS_HEADER dos; + PIMAGE_NT_HEADERS32 nt; + + dos = (PIMAGE_DOS_HEADER)raw; + + if( !raw || raw_size < sizeof(IMAGE_DOS_HEADER) ) + return false; + + if( dos->e_magic != IMAGE_DOS_SIGNATURE || dos->e_lfanew <= 0) + return false; + + nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); + + if( (addr_t)nt < (addr_t)raw) + return false; + + if(nt->Signature != IMAGE_NT_SIGNATURE) + return false; + + if(nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) + return false; + + if(nt->OptionalHeader.SectionAlignment < PAGE_SIZE) + { + if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment) + return false; + } + else if(nt->OptionalHeader.SectionAlignment < nt->OptionalHeader.FileAlignment) + return false; + + if(!IsPowerOf2(nt->OptionalHeader.SectionAlignment) || + !IsPowerOf2(nt->OptionalHeader.FileAlignment)) + return false; + + if(nt->FileHeader.NumberOfSections > 96) + return false; + + return true; +} + +md_t* __fastcall load_image(const char *path) +{ + PIMAGE_DOS_HEADER dos; + PIMAGE_NT_HEADERS32 nt; + + md_t *img_md; + + size_t img_size; + addr_t img_base; + count_t img_pages; + + size_t raw_size = 0; + void *raw; + + DBG("\nload image %s", path); + + raw = load_file(path, &raw_size); + + DBG(" raw = %x\n", raw); + + if( ! raw) + { + DBG("file not found: %s\n", path); + return NULL; + }; + + if( ! validate_pe(raw, raw_size) ) + { + DBG("invalid pe file %s\n", path); + mem_free(raw); + return NULL; + } + + dos = (PIMAGE_DOS_HEADER)raw; + nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); + + img_size = nt->OptionalHeader.SizeOfImage; + + img_md = md_alloc(img_size, PG_SW); + + + if( !img_md) + { + mem_free(raw); + return NULL; + }; + + img_base = img_md->base; + + create_image(img_base, (addr_t)raw); + + mem_free(raw); + +// dos = (PIMAGE_DOS_HEADER)img_base; +// nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); + + return img_md; +}; + + +/* +addr_t get_proc_addr(addr_t module, char *name) +{ + PIMAGE_DOS_HEADER expdos; + PIMAGE_NT_HEADERS32 expnt; + PIMAGE_EXPORT_DIRECTORY exp; + u32_t *functions; + char **funcname; + int ind; + + expdos = (PIMAGE_DOS_HEADER)module; + expnt = MakePtr( PIMAGE_NT_HEADERS32, expdos, expdos->e_lfanew); + + exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,module, + expnt->OptionalHeader.DataDirectory[0].VirtualAddress); + + functions = MakePtr(DWORD*,exp->AddressOfFunctions,module); + funcname = MakePtr(char**,exp->AddressOfNames,module); + + for(ind=0; *funcname;funcname++,ind++) + { + if(!strcmp(name,MakePtr(char*,*funcname,module))) + return functions[ind] + module; + }; + return -1; +}; +*/ + + +void create_image(addr_t img_base, addr_t raw) +{ + PIMAGE_DOS_HEADER dos; + PIMAGE_NT_HEADERS32 nt; + PIMAGE_SECTION_HEADER img_sec; + + u32_t sec_align; + int i; + + +/* assumed that image is valid */ + + dos = (PIMAGE_DOS_HEADER)raw; + nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); + + sec_copy(img_base, raw, nt->OptionalHeader.SizeOfHeaders); + + img_sec = MakePtr(PIMAGE_SECTION_HEADER, nt, sizeof(IMAGE_NT_HEADERS32)); + + sec_align = nt->OptionalHeader.SectionAlignment; + + for(i=0; i< nt->FileHeader.NumberOfSections; i++) + { + addr_t src_ptr; + addr_t dest_ptr; + size_t sec_size; + + src_ptr = MakePtr(addr_t, raw, img_sec->PointerToRawData); + dest_ptr = MakePtr(addr_t,img_base, img_sec->VirtualAddress); + + if(img_sec->SizeOfRawData) + sec_copy(dest_ptr, src_ptr, img_sec->SizeOfRawData); + + sec_size = (img_sec->Misc.VirtualSize + sec_align -1) & -sec_align; + + if(sec_size > img_sec->SizeOfRawData) + sec_clear(dest_ptr + img_sec->SizeOfRawData, + sec_size - img_sec->SizeOfRawData); + img_sec++; + } + + if(nt->OptionalHeader.DataDirectory[5].Size) + { + PIMAGE_BASE_RELOCATION reloc; + +/* FIXME addr_t */ + + u32_t delta = (u32_t)img_base - nt->OptionalHeader.ImageBase; + + reloc = MakePtr(PIMAGE_BASE_RELOCATION, img_base, + nt->OptionalHeader.DataDirectory[5].VirtualAddress); + + while ( reloc->SizeOfBlock != 0 ) + { + u32_t cnt; + u16_t *entry; + u16_t reltype; + u32_t offs; + + cnt = (reloc->SizeOfBlock - sizeof(*reloc))/sizeof(u16_t); + entry = MakePtr( u16_t*, reloc, sizeof(*reloc) ); + + for ( i=0; i < cnt; i++ ) + { + u16_t *p16; + u32_t *p32; + + reltype = (*entry & 0xF000) >> 12; + offs = (*entry & 0x0FFF) + reloc->VirtualAddress; + switch(reltype) + { + case 1: + p16 = MakePtr(u16_t*, img_base, offs); + *p16+= (u16_t)(delta>>16); + break; + case 2: + p16 = MakePtr(u16_t*, img_base, offs); + *p16+= (u16_t)delta; + break; + case 3: + p32 = MakePtr(u32_t*, img_base, offs); + *p32+= delta; + } + entry++; + } + reloc = MakePtr(PIMAGE_BASE_RELOCATION, reloc,reloc->SizeOfBlock); + } + }; + + DBG("\ncreate pe base %x, size %x, %d sections\n\n",img_base, + nt->OptionalHeader.SizeOfImage, nt->FileHeader.NumberOfSections); +}; + + +bool link_image(addr_t img_base) +{ + PIMAGE_DOS_HEADER dos; + PIMAGE_NT_HEADERS32 nt; + + int warn = 0; + +/* assumed that image is valid */ + + dos = (PIMAGE_DOS_HEADER)img_base; + nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); + + if(nt->OptionalHeader.DataDirectory[1].Size) + { + PIMAGE_IMPORT_DESCRIPTOR imp; + + imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, img_base, + nt->OptionalHeader.DataDirectory[1].VirtualAddress); + + + + while ( 1 ) + { + PIMAGE_THUNK_DATA32 thunk; + + PIMAGE_DOS_HEADER expdos; + PIMAGE_NT_HEADERS32 expnt; + PIMAGE_EXPORT_DIRECTORY exp; + + u32_t *iat; + char *libname; + addr_t *functions; + u16_t *ordinals; + char **funcname; + + dll_t *exp_dll; + + if ( (imp->TimeDateStamp==0 ) && (imp->Name==0) ) + break; + + libname=MakePtr(char*,imp->Name, img_base); + + DBG("import from %s\n",libname); + + exp_dll = find_dll(libname); + if(exp_dll != NULL) + { + DBG("find %s\n", exp_dll->img_name); + } + else + { + DBG("can't find %s\n", libname); + return false; + } + + exp = exp_dll->img_exp; + + functions = MakePtr(DWORD*,exp->AddressOfFunctions,exp_dll->img_base); + ordinals = MakePtr(WORD*, exp->AddressOfNameOrdinals,exp_dll->img_base); + funcname = MakePtr(char**, exp->AddressOfNames,exp_dll->img_base); + + thunk = MakePtr(PIMAGE_THUNK_DATA32, + imp->Characteristics, img_base); + iat= MakePtr(DWORD*,imp->FirstThunk, img_base); + + while ( 1 ) // Loop forever (or until we break out) + { + PIMAGE_IMPORT_BY_NAME ord; + addr_t addr; + + if ( thunk->u1.AddressOfData == 0 ) + break; + + if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG ) + { + // printf(" %4u\n", thunk->u1.Ordinal & 0xFFFF); + break; + } + else + { + ord = MakePtr(PIMAGE_IMPORT_BY_NAME, + thunk->u1.AddressOfData, img_base); + *iat=0; + + DBG("import %s", ord->Name); + + if(strncmp(ord->Name, + MakePtr(char*,funcname[ord->Hint],exp_dll->img_base),32)) + { + int ind; + char **names=funcname; + + for(names = funcname,ind = 0; + ind < exp->NumberOfNames; names++,ind++) + { + if(!strncmp(ord->Name,MakePtr(char*,*names,exp_dll->img_base),32)) + { + DBG(" \tat %x\n", functions[ind] + exp_dll->img_base); + *iat = functions[ind] + exp_dll->img_base; + break; + }; + }; + if(ind == exp->NumberOfNames) + { + DBG(" unresolved import %s\n",ord->Name); + warn=1; + }; + } + else + { + DBG(" \tat %x\n", functions[ord->Hint] + exp_dll->img_base); + *iat = functions[ord->Hint] + exp_dll->img_base; + }; + }; + thunk++; // Advance to next thunk + iat++; + } + imp++; // advance to next IMAGE_IMPORT_DESCRIPTOR + }; + }; + + if ( !warn ) + return true; + else + return false; +} + + diff --git a/kernel/branches/kolibri_pe/include/mm.h b/kernel/branches/kolibri_pe/include/mm.h index ab5d424d0..4867e7575 100644 --- a/kernel/branches/kolibri_pe/include/mm.h +++ b/kernel/branches/kolibri_pe/include/mm.h @@ -87,6 +87,7 @@ pfn_t alloc_page() __attribute__ ((deprecated)); md_t* __fastcall md_alloc(size_t size, u32_t flags) ; +void __fastcall md_free(md_t *md); void* __fastcall __export mem_alloc(size_t size, u32_t flags) asm ("MemAlloc"); void __fastcall __export mem_free(void *mem) asm ("MemFree"); diff --git a/kernel/branches/kolibri_pe/include/pe.h b/kernel/branches/kolibri_pe/include/pe.h new file mode 100644 index 000000000..3518dfb3b --- /dev/null +++ b/kernel/branches/kolibri_pe/include/pe.h @@ -0,0 +1,202 @@ + +typedef unsigned short WORD; +typedef unsigned int DWORD; +typedef unsigned int LONG; +typedef unsigned char BYTE; + +#define IMAGE_DOS_SIGNATURE 0x5A4D +#define IMAGE_NT_SIGNATURE 0x00004550 +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b + +#pragma pack(push,2) +typedef struct _IMAGE_DOS_HEADER +{ + WORD e_magic; + WORD e_cblp; + WORD e_cp; + WORD e_crlc; + WORD e_cparhdr; + WORD e_minalloc; + WORD e_maxalloc; + WORD e_ss; + WORD e_sp; + WORD e_csum; + WORD e_ip; + WORD e_cs; + WORD e_lfarlc; + WORD e_ovno; + WORD e_res[4]; + WORD e_oemid; + WORD e_oeminfo; + WORD e_res2[10]; + LONG e_lfanew; +} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER; +#pragma pack(pop) + + +#pragma pack(push,4) +typedef struct _IMAGE_FILE_HEADER +{ + WORD Machine; + WORD NumberOfSections; + DWORD TimeDateStamp; + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + WORD Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +typedef struct _IMAGE_DATA_DIRECTORY { + DWORD VirtualAddress; + DWORD Size; +} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +typedef struct _IMAGE_OPTIONAL_HEADER { + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + DWORD ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + DWORD SizeOfStackReserve; + DWORD SizeOfStackCommit; + DWORD SizeOfHeapReserve; + DWORD SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER; + +#pragma pack(pop) + + +#pragma pack(push,4) +typedef struct _IMAGE_NT_HEADERS +{ + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER OptionalHeader; +} IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32; + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER +{ + BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; + union + { + DWORD PhysicalAddress; + DWORD VirtualSize; + } Misc; + DWORD VirtualAddress; + DWORD SizeOfRawData; + DWORD PointerToRawData; + DWORD PointerToRelocations; + DWORD PointerToLinenumbers; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD Characteristics; +} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER; +#pragma pack(pop) + +#pragma pack(push,4) +typedef struct _IMAGE_BASE_RELOCATION { + DWORD VirtualAddress; + DWORD SizeOfBlock; +} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION; +#pragma pack(pop) + +typedef struct _IMAGE_IMPORT_DESCRIPTOR +{ + union + { + DWORD Characteristics; + DWORD OriginalFirstThunk; + }; + DWORD TimeDateStamp; + DWORD ForwarderChain; + DWORD Name; + DWORD FirstThunk; +} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR; + +typedef struct _IMAGE_THUNK_DATA32 +{ + union + { + DWORD ForwarderString; + DWORD Function; + DWORD Ordinal; + DWORD AddressOfData; + } u1; +} IMAGE_THUNK_DATA32,*PIMAGE_THUNK_DATA32; + +typedef struct _IMAGE_IMPORT_BY_NAME +{ + WORD Hint; + BYTE Name[1]; +} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME; + +#define IMAGE_ORDINAL_FLAG 0x80000000 + +typedef struct _IMAGE_EXPORT_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD Name; + DWORD Base; + DWORD NumberOfFunctions; + DWORD NumberOfNames; + DWORD AddressOfFunctions; + DWORD AddressOfNames; + DWORD AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY; + + +typedef struct +{ + link_t link; + + addr_t img_base; + size_t img_size; + char *img_name; + md_t *img_md; + + PIMAGE_NT_HEADERS32 img_hdr; + PIMAGE_SECTION_HEADER img_sec; + PIMAGE_EXPORT_DIRECTORY img_exp; + u32_t img_map[8]; /* mapped treads */ +}dll_t; + + +#define MakePtr( cast, ptr, addValue ) (cast)( (addr_t)(ptr) + (addr_t)(addValue) ) + + +dll_t * find_dll(const char *name); + + +md_t* __fastcall load_image(const char *path); + +void __export create_image(addr_t img_base, addr_t image) asm ("CreateImage"); + + diff --git a/kernel/branches/kolibri_pe/kernel.asm b/kernel/branches/kolibri_pe/kernel.asm index 98521e7fb..0fc4256f7 100644 --- a/kernel/branches/kolibri_pe/kernel.asm +++ b/kernel/branches/kolibri_pe/kernel.asm @@ -179,11 +179,12 @@ extrn _poweroff extrn _init extrn _init_mm +extrn @init_heap@8 +extrn _init_core_dll extrn @core_alloc@4 extrn @core_free@4 -extrn @init_heap@8 extrn @find_large_md@4 extrn _MemAlloc @@ -402,6 +403,8 @@ __core_restart: mov edx, 0x40000000 call @init_heap@8 + call _init_core_dll + mov esi, _16bit_start mov ecx, _16bit_end shr ecx, 2 diff --git a/kernel/branches/kolibri_pe/make.sh b/kernel/branches/kolibri_pe/make.sh deleted file mode 100755 index d49fd1221..000000000 --- a/kernel/branches/kolibri_pe/make.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -# This script does for linux the same as build.bat for DOS, -# it compiles the KoOS kernel, hopefully ;-) - -CLANG=$1; - -usage() -{ - echo "Usage: make.sh [en|ru|ge|et]" - exit 1 -} - -compile() -{ - fasm -m 65536 kernel.asm bin/kernel.mnt - rm -f lang.inc - exit 0 -} - - -if [ ! $CLANG ] ; then - usage -fi - -for i in "en" "ru" "ge" "et"; do - if [ $i == $CLANG ] ; then - echo "lang fix $i" > lang.inc - compile - fi -done -usage - - diff --git a/kernel/branches/kolibri_pe/makefile b/kernel/branches/kolibri_pe/makefile index ad8f59b49..fc5c5390f 100644 --- a/kernel/branches/kolibri_pe/makefile +++ b/kernel/branches/kolibri_pe/makefile @@ -30,6 +30,7 @@ PE_SRC:= \ mm.c \ slab.c \ heap.c \ + pe.c \ dll.c \ spinlock.c \ boot/boot.asm \