/* * 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; }
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; }
/*核心函数基本不做安全检查*/ 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; }
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; }
/*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; }
/* * 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; }
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; }
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 ) ); }
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; }
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; }
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); }
/* * 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); }