Example #1
0
//=========================================================================
// Return the physical address of the PT corresponding to address lAddress
//=========================================================================
struct PT *GetPT(struct PML4 *pml4, long lAddress, unsigned short pid)
{
	int pdIndex = GetPDIndex(lAddress);
	int pdpIndex = GetPDPIndex(lAddress);
	int pml4Index = GetPML4Index(lAddress);
	long pdp, pd, pt;

	pdp = VIRT(PML4,pml4) ->entries[pml4Index].value & 0xFFFFF000;
	if (!pdp)
	{
		long newpage = (long) AllocPage(pid);
		VIRT(PML4,pml4) ->entries[pml4Index].value = newpage | P | RW | US;
		pdp = newpage;
	}
	pd = VIRT(PDP,pdp) ->entries[pdpIndex].value & 0xFFFFF000;
	if (!pd)
	{
		long newpage = (long) AllocPage(pid);
		VIRT(PDP,pdp) ->entries[pdpIndex].value = newpage | P | RW | US;
		pd = newpage;
	}
	pt = VIRT(PD,pd) ->entries[pdIndex].value & 0xFFFFF000;
	if (!pt)
	{
		long newpage = (long) AllocPage(pid);
		VIRT(PD,pd) ->entries[pdIndex].value = newpage | P | RW | US;
		pt = newpage;
	}
	return (struct PT *) (pt & 0xFFFFF000);
}
Example #2
0
//=========================================================
// Copy the given page and all consecutive subsequent ones
//=========================================================
void CopyPages(long address, struct Task *task)
{
	address &= PageMask;
	// Get physical address of current PT

	struct PML4 *pml4 = (struct PML4 *) (task->cr3);
	struct PML4 *current_pml4 = (struct PML4 *) (currentTask->cr3);

	while (1)
	{
		struct PT *pt = GetPT(pml4, address, task->pid);
		struct PT *currentPT = GetPT(current_pml4, address, currentTask->pid);

		int i = GetPTIndex(address);
		if (!(VIRT(PT,currentPT) ->entries[i].value))
			break;

		// Copy the physical memory
		p_Address data = AllocPage(task->pid);
		//data += VAddr / 8;
		CreatePTEWithPT((struct PML4 *)task->cr3, data, address, task->pid,
				US | RW | P | 0x800);
		memcpy(
				(void *) PAGE(((VIRT(PT, pt)) ->entries[i].value)) + VAddr,
				(void *) PAGE(((VIRT(PT, currentPT)) ->entries[i].value)) + VAddr, PageSize);
		address += PageSize;
	}

}
Example #3
0
//=========================================================================
// Return the physical address of the PDP corresponding to address lAddress
//=========================================================================
struct PDP *GetPDP(struct PML4 *pml4, long lAddress, unsigned short pid)
{
	int pml4Index = GetPML4Index(lAddress);

	long pdp = VIRT(PML4,pml4) ->entries[pml4Index].value & 0xFFFFF000;
	if (!pdp)
	{
		long newpage = (long) AllocPage(pid);
		VIRT(PML4,pml4) ->entries[pml4Index].value = newpage | P | RW | US;
		pdp = newpage;
	}
	return (struct PDP *) (pdp & 0xFFFFF000);
}
Example #4
0
//=========================================================================
// Return the physical address of the PD corresponding to address lAddress
//=========================================================================
struct PD *GetPD(struct PML4 *pml4, long lAddress, unsigned short pid)
{
	int pdpIndex = lAddress >> 30 & 0x1FF;
	int pml4Index = lAddress >> 39 & 0x1FF;
	long pdp, pd;

	pdp = VIRT(PML4,pml4) ->entries[pml4Index].value & 0xFFFFF000;
	if (!pdp)
	{
		long newpage = (long) AllocPage(pid);
		VIRT(PML4,pml4) ->entries[pml4Index].value = newpage | P | RW | US;
		pdp = newpage;
	}
	pd = VIRT(PDP,pdp) ->entries[pdpIndex].value & 0xFFFFF000;
	if (!pd)
	{
		long newpage = (long) AllocPage(pid);
		VIRT(PDP,pdp) ->entries[pdpIndex].value = newpage | P | RW | US;
		pd = newpage;
	}
	return (struct PD *) (pd & 0xFFFFF000);
}
Example #5
0
//=====================================================
// Create a Page Table for a new process
// Return a pointer to the Page Directory of this table
//=====================================================
void * VCreatePageDir(unsigned short pid, unsigned short parentPid)
{
	struct PML4 *pml4;
	struct PD *pd;

	// Allocate the base page for the Page Table
	pml4 = (struct PML4 *) AllocPage(pid);

	VIRT(PML4,pml4) ->entries[GetPML4Index(VAddr)].value = virtualPDP | P
			| RW; // Physical to virtual addresses
	pd = GetPD(pml4, 0, pid);
	VIRT(PD,pd) ->entries[GetPDIndex(0)].value = kernelPT | P | RW; // Kernel entries

	if (parentPid == 0) // Just create some default PTEs
	// We need these two entries so that NewKernelTask can
	// access the data and stack pages of the new process.
	{
		long c;
		struct PT *pt = GetPT(pml4, UserData, pid);
		VIRT(PT,pt) ->entries[GetPTIndex(UserData)].value =
				AllocAndCreatePTE(TempUserData, pid, RW | P);
		c = TempUserData;

		asm ("invlpg %0;"
				:
				:"m"(*(char *)TempUserData)
		);

		pt = GetPT(pml4, KernelStack, pid);
		VIRT(PT,pt) ->entries[GetPTIndex(KernelStack)].value =
				AllocAndCreatePTE(TempUStack, pid, RW | P);

		pt = GetPT(pml4, UserStack, pid);
		VIRT(PT,pt) ->entries[GetPTIndex(UserStack)].value =
				AllocAndCreatePTE(TempUStack, pid, RW | P);
		c = TempUStack;
		asm ("invlpg %0;"
				:
				:"m"(*(char *)TempUStack)
		);
	}
int _cdecl 
main ( 
    int argc, char *argv[] ) 
{
    ULONG UserAddress = 0;
    ULONG PageCount  = 1 ;

    if ( argc > 1 ) {

        if ( strcmp ( argv[1], "/?" ) == 0 ) {
            Usage();
            goto Exit;
        }

        if ( strcmp ( argv[1], "-?" ) == 0 ) {
            Usage();
            goto Exit;
        }

        if ( sscanf ( argv[1], "%x", &UserAddress ) != 1 ) {
            Usage();
            goto Exit;
        }
    }

    if (  argc > 2 ) {
        if ( sscanf ( argv[2], "%d", &PageCount ) != 1 ) {
            Usage();
            goto Exit;
        }
        if ( PageCount == 0 ){
            PageCount = 1;
        }
    }

    AllocPage( (PUCHAR)UserAddress, PageCount );

Exit :
    return 0;
}
Example #7
0
static void* reserve_code(struct jit* jit, lua_State* L, size_t sz)
{
    struct page* page;
    size_t off = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->off : 0;
    size_t size = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->size : 0;

    if (off + sz >= size) {
        int i;
        uint8_t* pdata;
        cfunction func;

        /* need to create a new page */
        jit->pages = (struct page**) realloc(jit->pages, (++jit->pagenum) * sizeof(jit->pages[0]));

        size = ALIGN_UP(sz + LINKTABLE_MAX_SIZE + sizeof(struct page), jit->align_page_size);

        page = (struct page*) AllocPage(size);
        jit->pages[jit->pagenum-1] = page;
        pdata = (uint8_t*) page;
        page->size = size;
        page->off = sizeof(struct page);

        lua_newtable(L);

#define ADDFUNC(DLL, NAME) \
        lua_pushliteral(L, #NAME); \
        func = DLL ? (cfunction) GetProcAddressA(DLL, #NAME) : NULL; \
        func = func ? func : (cfunction) &NAME; \
        lua_pushcfunction(L, (lua_CFunction) func); \
        lua_rawset(L, -3)

        ADDFUNC(NULL, check_double);
        ADDFUNC(NULL, check_float);
        ADDFUNC(NULL, check_uint64);
        ADDFUNC(NULL, check_int64);
        ADDFUNC(NULL, check_int32);
        ADDFUNC(NULL, check_uint32);
        ADDFUNC(NULL, check_uintptr);
        ADDFUNC(NULL, check_enum);
        ADDFUNC(NULL, check_typed_pointer);
        ADDFUNC(NULL, check_typed_cfunction);
        ADDFUNC(NULL, check_complex_double);
        ADDFUNC(NULL, check_complex_float);
        ADDFUNC(NULL, unpack_varargs_stack);
        ADDFUNC(NULL, unpack_varargs_stack_skip);
        ADDFUNC(NULL, unpack_varargs_reg);
        ADDFUNC(NULL, unpack_varargs_float);
        ADDFUNC(NULL, unpack_varargs_int);
        ADDFUNC(NULL, push_cdata);
        ADDFUNC(NULL, push_int);
        ADDFUNC(NULL, push_uint);
        ADDFUNC(NULL, lua_pushinteger);
        ADDFUNC(NULL, push_float);
        ADDFUNC(jit->kernel32_dll, SetLastError);
        ADDFUNC(jit->kernel32_dll, GetLastError);
        ADDFUNC(jit->lua_dll, luaL_error);
        ADDFUNC(jit->lua_dll, lua_pushnumber);
        ADDFUNC(jit->lua_dll, lua_pushboolean);
        ADDFUNC(jit->lua_dll, lua_gettop);
        ADDFUNC(jit->lua_dll, lua_rawgeti);
        ADDFUNC(jit->lua_dll, lua_pushnil);
        ADDFUNC(jit->lua_dll, lua_callk);
        ADDFUNC(jit->lua_dll, lua_settop);
        ADDFUNC(jit->lua_dll, lua_remove);

//CHANGES: BEGIN

        ADDFUNC(jit->lua_dll, lua_pushlightuserdata);

//CHANGES: END

#undef ADDFUNC

        for (i = 0; extnames[i] != NULL; i++) {

            if (strcmp(extnames[i], "FUNCTION") == 0) {
                shred(pdata + page->off, 0, JUMP_SIZE);
                jit->function_extern = i;

            } else {
                lua_getfield(L, -1, extnames[i]);
                func = (cfunction) lua_tocfunction(L, -1);

                if (func == NULL) {
                    luaL_error(L, "internal error: missing link for %s", extnames[i]);
                }

                compile_extern_jump(jit, L, func, pdata + page->off);
                lua_pop(L, 1);
            }

            page->off += JUMP_SIZE;
        }

        page->freed = page->off;
        lua_pop(L, 1);

    } else {
        page = jit->pages[jit->pagenum-1];
        EnableWrite(page, page->size);
    }

    return (uint8_t*) page + page->off;
}
Example #8
0
void *malloc(size_t size)
{
	heap_t *Heap, *tmp_Heap;
	void *Address;
	if(size == 0)
		return NULL;
	if(Heap_Entries == 0)	//Es wurde bisher kein Speicher angefordert
	{
		uint64_t Pages = (size + sizeof(heap_t)) / 4096 + 1;
		//if((size + sizeof(heap_t)) % 4096 != 0) Pages++;
		Heap_Base = AllocPage(Pages);					//Pages reservieren
		if(Heap_Base == NULL) return NULL;
		Heap = (heap_t*)Heap_Base;
		Heap->Next = NULL;
		Heap->Prev = NULL;
		Heap->Length = size;							//Grösse des Heaps entspricht dem angeforderten Speicherplatz
		//Heap->Length = Pages * 4096 - sizeof(heap_t);	//Speicher für den Header abziehen

		//Jetzt angefordeten Speicher reservieren
		Address = (void*)((uintptr_t)Heap + sizeof(heap_t));
		Heap->Flags = HEAP_FLAGS | HEAP_RESERVED;		//Reserved-Bit setzen
		if((Heap->Length + 2 * sizeof(heap_t)) <= (Pages * 4096))
		{
			tmp_Heap = Address + size;
			setupNewHeapEntry(Heap, tmp_Heap);
			tmp_Heap->Length = Pages * 4096 - size - 2 * sizeof(heap_t);
			//tmp_Heap->Length = Heap->Length - size - sizeof(heap_t);//Heapheader abziehen
			//Heap->Length = size;						//Länge des ersten Speicherbereichs aktualisieren
			Heap_Entries = 2;
		}
		else											//Hat nur ein Header Platz, gebe den Speicher dem vorhergehenden Header
		{
			Heap_Entries = 1;
		}
	}
	else						//Es wurde schon Speicher reserviert
	{
		Heap = Heap_Base;
		uint64_t i;
		//Die Header durchsuchen und schauen, ob dort freier Speicher verfügbar ist
		for(i = 0; i < Heap_Entries; i++)
		{
			if((Heap->Flags & HEAP_RESERVED) || (Heap->Length < size))
			{
				if(Heap->Next == NULL) break;		//Es sind keine weiteren Headers vorhanden
				Heap = Heap->Next;
				continue;							//Wenn dieser Speicherbereich reserviert oder zu klein ist, zum nächsten gehen
			}
			if (Heap->Length >= size + sizeof(heap_t))	//Speicherbereich zu gross und Platz für einen Header => Speicherbereich anpassen
			{
				Address = (void*)((uintptr_t)Heap + sizeof(heap_t));
				tmp_Heap = Address + size;
				setupNewHeapEntry(Heap, tmp_Heap);
				tmp_Heap->Length = Heap->Length - size - sizeof(heap_t);
				Heap->Length = size;				//Länge anpassen
				Heap->Flags |= HEAP_RESERVED;		//Als reserviert markieren
				return Address;
			}
			else							//Wenn kein neuer Header platz hat, dann ist der Speicherbereich halt zu gross
			{
				Heap->Flags |= HEAP_RESERVED;		//Als reserviert markieren
				return (void*)((uintptr_t)Heap + sizeof(heap_t));
			}
		}

		//Wenn kein passender Heapeintrag gefunden wurde, dann muss neuer Speicher angefordert werden
		/*if (Heap->Flags & HEAP_RESERVED)
		{*/
			tmp_Heap = Heap;
			uint64_t Pages = (size + sizeof(heap_t)) / 4096 + 1;
			//if((size + sizeof(heap_t)) % 4096 != 0) Pages++;
			Heap = AllocPage(Pages);						//Eine Page reservieren
			if(Heap == NULL) return NULL;
			Heap_Entries++;
			tmp_Heap->Next = Heap;
			Heap->Next = NULL;
			Heap->Prev = tmp_Heap;
			Heap->Length = size;
			//Heap->Length = Pages * 4096 - sizeof(heap_t);	//Speicher für den Header abziehen
			Address = (void*)((uintptr_t)Heap + sizeof(heap_t));
			Heap->Flags = HEAP_FLAGS | HEAP_RESERVED;		//Reserved-Bit setzen

			if (Heap->Length <= Pages * 4096 - 2 * sizeof(heap_t))
			{
				tmp_Heap = Address + size;
				setupNewHeapEntry(Heap, tmp_Heap);
				tmp_Heap->Length = Pages * 4096 - size - 2 * sizeof(heap_t);
			}
		/*}
		else		//Der aktuelle Speicherbereich ist zu klein		TODO: Funktioniert nicht wegen Fragmentierung
		{
			size_t additionalSize = size - Heap->Length;
			uint64_t Pages = additionalSize / 4096 + 1;
			if(AllocPage(Pages) == NULL) return NULL;       //Eine Page reservieren
			Heap->Length += Pages * 4096;
			Address = (void*)((uintptr_t)Heap + sizeof(heap_t));
			Heap->Flags = HEAP_FLAGS | HEAP_RESERVED;		//Reserved-Bit setzen

			if (additionalSize <= Pages * 4096 - sizeof(heap_t))
			{
				tmp_Heap = Address + size;
				setupNewHeapEntry(Heap, tmp_Heap);
			}
		}*/
		//Neuer Speicher anfordern
		/*Heap = Heap_Base;
		register uint64_t i;
		for(i = 0; i < Heap_Entries; i++)
			Heap = Heap->Next;
		size_t AllocSize = size - Heap->Length;
		uint64_t Pages = (size % 4096 != 0) ? size / 4096 + 1 : size / 4096;
		tmp_Heap = AllocPage(Pages);*/
	}
	return Address;
}
Example #9
0
	System::UIntPtr^ PREFIXED(AllocManager)::Alloc()
	{
		return gcnew System::UIntPtr(AllocPage());
	}