Esempio n. 1
0
/*
 * convert malloced or non-malloced buffer to a Block.
 * used to build custom Block allocators.
 *
 * buf must be at least blocksize(usable) bytes.
 */
Block *
mem2block(void *buf, ulong usable, int malloced)
{
	Block *b;

	if(buf == nil)
		return nil;

	b = (Block *)buf;
	b->next = nil;
	b->list = nil;
	b->free = 0;
	b->flag = 0;
	b->ref = 0;
	b->magic = Bmagic;
	_xinc(&b->ref);

	/* align start of data portion by rounding up */
	b->base = (uchar*)ALIGNUP((ulong)b + sizeof(Block));

	/* align end of data portion by rounding down */
	b->lim = (uchar*)b + (malloced? msize(b): blocksize(usable));
	b->lim = (uchar*)((ulong)b->lim & ~(BLOCKALIGN-1));

	/* leave sluff at beginning for added headers */
	b->wp = b->rp = b->lim - ALIGNUP(usable);
	if(b->rp < b->base)
		panic("mem2block: b->rp < b->base");
	if(b->lim > (uchar*)b + (malloced? msize(b): blocksize(usable)))
		panic("mem2block: b->lim beyond Block end");
	return b;
}
Esempio n. 2
0
int	StackAllocator::initFrameMemorySystem(int sizeInBytes, int bytesAlignment)
{
	// Make sure sizeInBytes is amultiple of bytesAlignment
	sizeInBytes = ALIGNUP( sizeInBytes, bytesAlignment );

	m_pMemoryBlock = (u8*)malloc(sizeInBytes + bytesAlignment);

	if ( m_pMemoryBlock == 0 )
	{
		return 1;
	}

	m_iBytesAlignment = bytesAlignment;

	// Set up base pointer
	m_pBaseandCap[0] = (u8*)ALIGNUP( m_pMemoryBlock, bytesAlignment );

	m_pBaseandCap[1] = (u8*)ALIGNUP( m_pMemoryBlock + sizeInBytes, bytesAlignment );

	// Init lower and upped frame pointer

	m_pFrame[0] = m_pBaseandCap[0];
	m_pFrame[1] = m_pBaseandCap[1];

	return 0;
}
Esempio n. 3
0
/*核心函数基本不做安全检查*/
INI_RESULT RBFrameAlloctor::init(size_t tsize)
{
	RBFN(RBFrameAlloctor::init);

#if _DEBUG
	printf("RBFrameAlloctor is starting up...\n");
#endif
	_byte_alignment = BYTEALIGN;
	tsize = ALIGNUP(tsize,_byte_alignment);
	_all_memory = tsize + _byte_alignment;
	//加上_byte_alignment防止在对齐内存时候栈顶越界
	_pmemory = (u8*)malloc(_all_memory);
	if(!_pmemory)
	{
		//log???
#ifdef _DEBUG
		printf("初始化内存分配失败!\n");
#endif
		return SYSTEM_MEMORY_SHORT;
	}

	_pbase = (u8*)ALIGNUP(_pmemory,_byte_alignment);
	_pcap = (u8*)ALIGNUP(_pmemory+tsize,_byte_alignment);

	_pframe_base = _pbase;
	_pframe_cap = _pcap;

	return SYSTEM_MEMORY_SUCCESS;

}
Esempio n. 4
0
void* StackAllocator::allocateFrameMemory(int bytes, int heapNum)
{
	u8*	mem;

	// Align the request size
	bytes = ALIGNUP( bytes, m_iBytesAlignment);

	// Check for available memory
	if (m_pFrame[0] + bytes > m_pFrame[1])
	{
		// insufficient memory
		return 0;
	}

	if (heapNum)
	{
		// Allocate form upped heap, down
		m_pFrame[1] -= bytes;
		mem = m_pFrame[1];
	}
	else
	{
		// Allocate form lower heap, up
		mem = m_pFrame[0];
		m_pFrame[0] += bytes;
	}

	return (void*)mem;
}
Esempio n. 5
0
/*0 low 1 high*/
void* RBFrameAlloctor::alloc(size_t tsize,MPOS tpos)
{
	RBFN(RBFrameAlloctor::alloc);

	u8* _pret;

	tsize = ALIGNUP(tsize,_byte_alignment);

	if(_pframe_base+tsize>_pframe_cap)
	{
		//log???
#ifdef _DEBUG
		printf("动态内存分配不足!即将退出!\n");
		getchar();
#endif
		//exit(0);
		//仅仅测试
		return NULL;
	}

	if(!tpos)
	{
		_pret = _pframe_base;
		_pframe_base += tsize;
	}
	else
	{
		_pframe_cap -= tsize;
		_pret = _pframe_cap;
	}

	return (void*)_pret;

}
Esempio n. 6
0
/*
 * Allocate a block.
 */
void* kmalloc(size_t size)
{
	struct block* b;

	size = ALIGNUP(size) + sizeof(struct block);
	b = find_smallest(size);
	if (!b)
		return NULL;

	split_block(b, size);
	#if defined(DEBUG_MEMORY)
		kprintf("mem: alloc %x+%x\n", b, b->length);
	#endif
	return b+1;
}
Esempio n. 7
0
static int quicktest1(unsigned long arg)
{
	struct gru_message_queue_desc mqd;
	void *p, *mq;
	unsigned long *dw;
	int i, ret = -EIO;
	char mes[GRU_CACHE_LINE_BYTES], *m;

	/* Need  1K cacheline aligned that does not cross page boundary */
	p = kmalloc(4096, 0);
	if (p == NULL)
		return -ENOMEM;
	mq = ALIGNUP(p, 1024);
	memset(mes, 0xee, sizeof(mes));
	dw = mq;

	gru_create_message_queue(&mqd, mq, 8 * GRU_CACHE_LINE_BYTES, 0, 0, 0);
	for (i = 0; i < 6; i++) {
		mes[8] = i;
		do {
			ret = gru_send_message_gpa(&mqd, mes, sizeof(mes));
		} while (ret == MQE_CONGESTION);
		if (ret)
			break;
	}
	if (ret != MQE_QUEUE_FULL || i != 4) {
//		printk(KERN_DEBUG "GRU:%d quicktest1: unexpect status %d, i %d\n",
;
		goto done;
	}

	for (i = 0; i < 6; i++) {
		m = gru_get_next_message(&mqd);
		if (!m || m[8] != i)
			break;
		gru_free_message(&mqd, m);
	}
	if (i != 4) {
//		printk(KERN_DEBUG "GRU:%d quicktest2: bad message, i %d, m %p, m8 %d\n",
;
		goto done;
	}
	ret = 0;

done:
	kfree(p);
	return ret;
}
Esempio n. 8
0
void* CHeap1::Alloc( uint size ) {
	Node *node = pSentinel->pNextFree;

	while ( node != NULL ) {
		if ( node->GetDataSize() > size ) {
			// found a suitable node
			break;
		}
		node = node->pNextFree;
	}

	if ( node == NULL ) {
		return NULL;
	}

	Node *NextFree = node->pNextFree;
	Node *PrevFree = node->pPrevFree;
	Node *NextMem = node->pNextMem;
	Node *PrevMem = node->pPrevMem;

	if ( node->GetDataSize() - size < SPLIT_THRESHOLD ) {
		// will not divide
		PrevFree->pNextFree = NextFree;
		if ( NextFree ) NextFree->pPrevFree = PrevFree;	

		node->pPrevFree = node->pNextFree = NULL;
	}
	else {
		void* addr = (void*)( (char*) node + size + sizeof( Node ) );
		addr = (void*)ALIGNUP( (uint)addr, AlignMent );

		Node* new_node = (Node*)( addr );
		new_node->pPrevMem = node;
		new_node->pNextMem = NextMem;
		new_node->pPrevFree = PrevFree;
		new_node->pNextFree = NextFree;

		if ( PrevFree ) PrevFree->pNextFree = new_node;
		if ( NextFree ) NextFree->pPrevFree = new_node;

		if ( NextMem && NextMem != pHeapEnd ) NextMem->pPrevMem = new_node;
		node->pNextMem = new_node;

		node->pPrevFree = node->pNextFree = NULL;
	}
	
	return (void*)( (char*)node + sizeof( Node ) );
}
Esempio n. 9
0
bool CHeap1::CreateFromBuffer( void* buffer, uint size ) {
	pHeapMemoryStart = buffer;
	void *_start = (void*) ALIGNUP( (uint)buffer, AlignMent );
	void *_end = (void*) ALIGNDOWN( (uint)buffer + size, AlignMent );
	pHeapEnd = _end;

	pSentinel = (Node*)_start;
	Node* new_node = (Node*)_start + 1;

	pSentinel->pPrevMem = NULL;
	pSentinel->pNextMem = new_node;
	pSentinel->pPrevFree = NULL;
	pSentinel->pNextFree = new_node;

	new_node->pPrevMem = pSentinel;
	new_node->pNextMem = (Node*)_end;
	new_node->pPrevFree = pSentinel;
	new_node->pNextFree = NULL;
}
Esempio n. 10
0
static void _load_errlist(void)
{
	struct stat st;
	int fd = open(_PATH_LIBERR, O_RDONLY|O_CLOEXEC);
	if (fd < 0)
		return;
	if (fstat(fd, &st) < 0 || !S_ISREG(st.st_mode))
		goto bad;
	__sys_errlist = sbrk(ALIGNUP(st.st_size));
	if (__sys_errlist == (void *) -1)
		goto bad;
	if (read(fd,__sys_errlist, st.st_size) == st.st_size) {
		__sys_nerr = *__sys_errlist;
		__sys_errptr = (uint16_t *)__sys_errlist + 1;
		close(fd);
		return;
	}
bad:
	close(fd);
	__sys_errlist = NULL;
	return;
}
Esempio n. 11
0
arg_t _execve(void)
{
	/* We aren't re-entrant where this matters */
	uint8_t hdr[16];
	staticfast inoptr ino;
	char **nargv;		/* In user space */
	char **nenvp;		/* In user space */
	struct s_argblk *abuf, *ebuf;
	int argc;
	uint16_t progptr;
	uint16_t progload;
	staticfast uint16_t top;
	uint16_t bin_size;	/* Will need to be bigger on some cpus */
	uint16_t bss;

	top = ramtop;

	if (!(ino = n_open_lock(name, NULLINOPTR)))
		return (-1);

	if (!((getperm(ino) & OTH_EX) &&
	      (ino->c_node.i_mode & F_REG) &&
	      (ino->c_node.i_mode & (OWN_EX | OTH_EX | GRP_EX)))) {
		udata.u_error = EACCES;
		goto nogood;
	}

	setftime(ino, A_TIME);

	udata.u_offset = 0;
	udata.u_count = 16;
	udata.u_base = hdr;
	udata.u_sysio = true;

	readi(ino, 0);
	if (udata.u_done != 16) {
		udata.u_error = ENOEXEC;
		goto nogood;
	}

	if (!header_ok(hdr)) {
		udata.u_error = ENOEXEC;
		goto nogood2;
	}

	progload = hdr[7] << 8;
	if (progload == 0)
		progload = PROGLOAD;

	top = *(uint16_t *)(hdr + 8);
	if (top == 0)	/* Legacy 'all space' binary */
		top = ramtop;
	else	/* Requested an amount, so adjust for the base */
		top += progload;

	bss = *(uint16_t *)(hdr + 14);

	/* Binary doesn't fit */
	/* FIXME: review overflows */
	bin_size = ino->c_node.i_size;
	progptr = bin_size + 1024 + bss;
	if (progload < PROGLOAD || top - progload < progptr || progptr < bin_size) {
		udata.u_error = ENOMEM;
		goto nogood2;
	}

	udata.u_ptab->p_status = P_NOSLEEP;

	/* If we made pagemap_realloc keep hold of some defined area we
	   could in theory just move the arguments up or down as part of
	   the process - that would save us all this hassle but replace it
	   with new hassle */

	/* Gather the arguments, and put them in temporary buffers. */
	abuf = (struct s_argblk *) tmpbuf();
	/* Put environment in another buffer. */
	ebuf = (struct s_argblk *) tmpbuf();

	/* Read args and environment from process memory */
	if (rargs(argv, abuf) || rargs(envp, ebuf))
		goto nogood3;	/* SN */

	/* This must be the last test as it makes changes if it works */
	/* FIXME: once we sort out chmem we can make stack and data
	   two elements. We never allocate 'code' as there is no split I/D */
	/* This is only safe from deadlocks providing pagemap_realloc doesn't
	   sleep */
	if (pagemap_realloc(0, top - MAPBASE, 0))
		goto nogood3;

	/* From this point on we are commmited to the exec() completing */

	/* Core dump and ptrace permission logic */
#ifdef CONFIG_LEVEL_2
	/* Q: should uid == 0 mean we always allow core */
	if ((!(getperm(ino) & OTH_RD)) ||
		(ino->c_node.i_mode & (SET_UID | SET_GID)))
		udata.u_flags |= U_FLAG_NOCORE;
	else
		udata.u_flags &= ~U_FLAG_NOCORE;
#endif
	udata.u_top = top;
	udata.u_ptab->p_top = top;

	/* setuid, setgid if executable requires it */
	if (ino->c_node.i_mode & SET_UID)
		udata.u_euid = ino->c_node.i_uid;

	if (ino->c_node.i_mode & SET_GID)
		udata.u_egid = ino->c_node.i_gid;

	/* FIXME: In the execve case we may on some platforms have space
	   below PROGLOAD to clear... */

	/* We are definitely going to succeed with the exec,
	 * so we can start writing over the old program
	 */
	uput(hdr, (uint8_t *)progload, 16);
	/* At this point, we are committed to reading in and
	 * executing the program. This call must not block. */

	close_on_exec();

	/*
	 *  Read in the rest of the program, block by block. We rely upon
	 *  the optimization path in readi to spot this is a big move to user
	 *  space and move it directly.
	 */

	 progptr = progload + 16;
	 if (bin_size > 16) {
		bin_size -= 16;
		udata.u_base = (uint8_t *)progptr;		/* We copied the first block already */
		udata.u_count = bin_size;
		udata.u_sysio = false;
		readi(ino, 0);
		if (udata.u_done != bin_size)
			goto nogood4;
		progptr += bin_size;
	}
	/* Wipe the memory in the BSS. We don't wipe the memory above
	   that on 8bit boxes, but defer it to brk/sbrk() */
	uzero((uint8_t *)progptr, bss);

	/* Set initial break for program */
	udata.u_break = (int)ALIGNUP(progptr + bss);

	/* Turn off caught signals */
	memset(udata.u_sigvec, 0, sizeof(udata.u_sigvec));

	// place the arguments, environment and stack at the top of userspace memory,

	// Write back the arguments and the environment
	nargv = wargs(((char *) top - 2), abuf, &argc);
	nenvp = wargs((char *) (nargv), ebuf, NULL);

	// Fill in udata.u_name with program invocation name
	uget((void *) ugetw(nargv), udata.u_name, 8);
	memcpy(udata.u_ptab->p_name, udata.u_name, 8);

	tmpfree(abuf);
	tmpfree(ebuf);
	i_deref(ino);

	/* Shove argc and the address of argv just below envp
	   FIXME: should flip them in crt0.S of app for R2L setups
	   so we can get rid of the ifdefs */
#ifdef CONFIG_CALL_R2L	/* Arguments are stacked the 'wrong' way around */
	uputw((uint16_t) nargv, nenvp - 2);
	uputw((uint16_t) argc, nenvp - 1);
#else
	uputw((uint16_t) nargv, nenvp - 1);
	uputw((uint16_t) argc, nenvp - 2);
#endif

	/* Set stack pointer for the program */
	udata.u_isp = nenvp - 2;

	/* Start execution (never returns) */
	udata.u_ptab->p_status = P_RUNNING;
	doexec(progload);

	/* tidy up in various failure modes */
nogood4:
	/* Must not run userspace */
	ssig(udata.u_ptab, SIGKILL);
nogood3:
	udata.u_ptab->p_status = P_RUNNING;
	tmpfree(abuf);
	tmpfree(ebuf);
nogood2:
nogood:
	i_unlock_deref(ino);
	return (-1);
}
Esempio n. 12
0
/*
 * convert the size of a desired buffer to the size needed
 * to include Block overhead and alignment.
 */
ulong
blocksize(ulong size)
{
	return ALIGNUP(sizeof(Block)) + Hdrspc + ALIGNUP(size);
}