Example #1
0
Area* AddressSpace::CreateArea(const char name[], unsigned int size, AreaWiring wiring,
	PageProtection protection, PageCache *cache, off_t offset, unsigned int va,
	int flags)
{
	if (size % PAGE_SIZE != 0 || size == 0)
		return 0;

	if (cache != 0 && cache->Commit(offset + size) != offset + size)
		return 0;

	fAreaLock.LockWrite();
	if (va == INVALID_PAGE)
		va = FindFreeRange(size, flags);
	else if (va % PAGE_SIZE != 0 || !fAreas.IsRangeFree(va, va + size - 1))
		va = INVALID_PAGE;

	Area *area = 0;
	if (va != INVALID_PAGE) {
		area = new Area(name, protection, cache, offset, wiring);
		fAreas.Add(area, va, va + size - 1);
		if (wiring & AREA_WIRED) {
			for (unsigned int aroffs = 0; aroffs < size; aroffs += PAGE_SIZE) {
				Page *page = area->GetPageCache()->GetPage(area->GetCacheOffset()
					+ aroffs, false);
				page->Wire();
				fPhysicalMap->Map(va + aroffs, page->GetPhysicalAddress(), protection);
			}
		}
	}

	fChangeCount++;
	fAreaLock.UnlockWrite();
	return area;
}
Example #2
0
Area* AddressSpace::MapPhysicalMemory(const char name[], unsigned int pa,
	unsigned int size, PageProtection protection)
{
	fAreaLock.LockWrite();
	unsigned int va = FindFreeRange(size);
	if (va == INVALID_PAGE) {
		fAreaLock.UnlockWrite();
		return 0;
	}

	Area *area = new Area(name, protection, 0, 0, AREA_WIRED);
	fAreas.Add(area, va, va + size - 1);
	for (unsigned int aroffs = 0; aroffs < size; aroffs += PAGE_SIZE)
		fPhysicalMap->Map(va + aroffs, pa + aroffs, protection);

	fChangeCount++;
	fAreaLock.UnlockWrite();
	return area;
}
Example #3
0
void *Elf32Load(int FD, Elf32_Ehdr *hdr)
{
	ENTER("iFD", FD);
	
	// Check for a program header
	if(hdr->e_phoff == 0) {
		#if DEBUG_WARN
		Warning("ELF File does not contain a program header\n");
		#endif
		LEAVE('n');
		return NULL;
	}
	
	// Read Program Header Table
	Elf32_Phdr* phtab = malloc( sizeof(Elf32_Phdr) * hdr->e_phnum );
	if( !phtab ) {
		LEAVE('n');
		return NULL;
	}
	LOG("hdr.e_phoff = 0x%08x\n", hdr->e_phoff);
	acess__SysSeek(FD, hdr->e_phoff, ACESS_SEEK_SET);
	acess__SysRead(FD, phtab, sizeof(Elf32_Phdr) * hdr->e_phnum);
	
	// Count Pages
	unsigned int iPageCount = 0;
	LOG("hdr.e_phnum = %i\n", hdr->e_phnum);
	for( unsigned int i = 0; i < hdr->e_phnum; i++ )
	{
		// Ignore Non-LOAD types
		if(phtab[i].p_type != PT_LOAD)
			continue;
		iPageCount += ((phtab[i].p_vaddr&0xFFF) + phtab[i].p_memsz + 0xFFF) >> 12;
		LOG("phtab[%i] = {p_vaddr:0x%x, p_memsz:0x%x}\n", i, phtab[i].p_vaddr, phtab[i].MemSize);
	}
	
	LOG("iPageCount = %i\n", iPageCount);
	
	// Allocate Information Structure
	//ret = malloc( sizeof(tBinary) + sizeof(tBinaryPage)*iPageCount );
	// Fill Info Struct
	//ret->Entry = hdr.entrypoint;
	//ret->Base = -1;		// Set Base to maximum value
	//ret->NumPages = iPageCount;
	//ret->Interpreter = NULL;

	// Prescan for base and size
	uint32_t	max = 0;
	uint32_t	base = UINT32_MAX;
	for( unsigned int i = 0; i < hdr->e_phnum; i ++)
	{
		if( phtab[i].p_type != PT_LOAD )
			continue;
		if( phtab[i].p_vaddr < base )
			base = phtab[i].p_vaddr;
		if( phtab[i].p_vaddr + phtab[i].p_memsz > max )
			max = phtab[i].p_vaddr + phtab[i].p_memsz;
	}

	LOG("base = %08x, max = %08x\n", base, max);

	uint32_t	baseDiff = 0;
	if( base == 0 ) {
		// Find a nice space (47 address bits allowed)
		base = FindFreeRange( max, 47 );
		LOG("new base = %08x\n", base);
		if( base == 0 )	return NULL;
		baseDiff = base;
	}
	
	// Load Pages
	for( unsigned int i = 0; i < hdr->e_phnum; i++ )
	{
		// Get Interpreter Name
		if( phtab[i].p_type == PT_INTERP )
		{
			char *tmp;
			//if(ret->Interpreter)	continue;
			tmp = malloc(phtab[i].p_filesz);
			acess__SysSeek(FD, phtab[i].p_offset, ACESS_SEEK_SET);
			acess__SysRead(FD, tmp, phtab[i].p_filesz);
			//ret->Interpreter = Binary_RegInterp(tmp);
			LOG("Interpreter '%s'\n", tmp);
			free(tmp);
			continue;
		}
		// Ignore non-LOAD types
		if(phtab[i].p_type != PT_LOAD)	continue;
		
		LOG("phtab[%i] = PT_LOAD {Adj p_vaddr:0x%x, p_offset:0x%x, p_filesz:0x%x, p_memsz:0x%x}\n",
			i, phtab[i].p_vaddr+baseDiff, phtab[i].p_offset, phtab[i].p_filesz, phtab[i].p_memsz);
		
		uint64_t addr = phtab[i].p_vaddr + baseDiff;

		if( AllocateMemory( addr, phtab[i].p_memsz ) ) {
			fprintf(stderr, "Elf_Load: Unable to map memory at 0x%"PRIx64" (0x%x bytes)\n",
				addr, phtab[i].p_memsz);
			free( phtab );
			return NULL;
		}
		
		acess__SysSeek(FD, phtab[i].p_offset, ACESS_SEEK_SET);
		acess__SysRead(FD, PTRMK(void, addr), phtab[i].p_filesz);
		memset( PTRMK(char, addr) + phtab[i].p_filesz, 0, phtab[i].p_memsz - phtab[i].p_filesz );
	}
	
	// Clean Up
	free(phtab);
	// Return
	LEAVE('p', base);
	return PTRMK(void, base);
}