Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 890 → Rev 892

/kernel/branches/kolibri_pe/make.sh
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/kernel/branches/kolibri_pe/build.bat
File deleted
/kernel/branches/kolibri_pe/core/dll.c
5,244 → 5,75
#include <link.h>
#include <mm.h>
#include <slab.h>
#include <pe.h>
 
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef unsigned int LONG;
typedef unsigned char BYTE;
int __stdcall strncmp(const char *s1, const char *s2, size_t n);
 
#define IMAGE_DOS_SIGNATURE 0x5A4D
#define IMAGE_NT_SIGNATURE 0x00004550
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
static dll_t core_dll;
 
#pragma pack(push,2)
typedef struct _IMAGE_DOS_HEADER
static char* strupr(char *str )
{
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)
char *p;
unsigned char c;
 
 
#pragma pack(push,4)
typedef struct _IMAGE_FILE_HEADER
p = str;
while( (c = *p) )
{
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
if( c >= 'a' && c <= 'z' )
*p = c - 'a' + 'A';
++p;
}
 
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
return( str );
}
 
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
void init_core_dll()
{
PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS32 nt;
PIMAGE_EXPORT_DIRECTORY exp;
 
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;
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);
 
#pragma pack(pop)
list_initialize(&core_dll.link);
 
core_dll.img_base = LOAD_BASE;
core_dll.img_size = nt->OptionalHeader.SizeOfImage;
core_dll.img_md = NULL;
 
#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;
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));
 
#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;
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 );
};
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
dll_t * find_dll(const char *name)
{
WORD Hint;
BYTE Name[1];
} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME;
dll_t* dll = &core_dll;
 
#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
do
{
addr_t base;
addr_t frame;
md_t *md;
if( !strncmp(name,dll->img_name,16))
return dll;
 
IMAGE_OPTIONAL_HEADER *opthdr;
dll = (dll_t*)dll->link.next;
 
}dll_t;
}while(&dll->link != &core_dll.link);
 
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");
return NULL;
};
 
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");
};
 
int __stdcall strncmp(const char *s1, const char *s2, size_t n);
 
 
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)
{
md_t *md;
 
md = load_image(path);
 
if( md )
return (void*)md->base;
 
return NULL;
};
 
typedef struct
{
char srv_name[16]; // ASCIIZ string
271,6 → 102,8
if( ! md )
return 0;
 
if( link_image( md->base ) )
{
dos = (PIMAGE_DOS_HEADER)md->base;
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
 
284,405 → 117,10
 
return srv;
}
 
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)
md_free( 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
}
};
 
*/
/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" #
 
/kernel/branches/kolibri_pe/core/heap.c
110,7 → 110,7
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
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 *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
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 *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
{
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
{
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
};
 
 
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
{
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
 
tmp = (md_t*)sheap.used.next;
 
while((link_t*)tmp != &sheap.used)
while( &tmp->link != &sheap.used)
{
if( tmp->base == (addr_t)mem )
{
732,38 → 770,10
 
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);
 
safe_sti(efl);
/kernel/branches/kolibri_pe/core/pe.c
0,0 → 1,414
 
#include <types.h>
#include <core.h>
#include <spinlock.h>
#include <link.h>
#include <mm.h>
#include <slab.h>
#include <pe.h>
 
 
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;
}
 
 
/kernel/branches/kolibri_pe/include/mm.h
87,6 → 87,7
 
 
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");
/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");
 
 
/kernel/branches/kolibri_pe/kernel.asm
179,11 → 179,12
 
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
mov edx, 0x40000000
call @init_heap@8
 
call _init_core_dll
 
mov esi, _16bit_start
mov ecx, _16bit_end
shr ecx, 2
/kernel/branches/kolibri_pe/makefile
30,6 → 30,7
mm.c \
slab.c \
heap.c \
pe.c \
dll.c \
spinlock.c \
boot/boot.asm \