comm_msg_t * comm_msg_new(uint32_t size, size_t size_max) { comm_msg_t *msg; if (size_max) assert(size <= size_max); msg = malloc(sizeof(*msg)); if (!msg) { error("allocating comm message\n"); return NULL; } msg->used = msg->read = 0; msg->size = WORD_ALIGN(size); msg->size_max = WORD_ALIGN(size_max); msg->buf = malloc(msg->size); if (!msg->buf) { free(msg); error("allocating comm message buffer\n"); return NULL; } return msg; }
/* Returns the number of bytes offset between FROM_REG and TO_REG for the current function. As a side effect it fills in the current_frame_info structure, if the data is available. */ unsigned int fr30_compute_frame_size (int from_reg, int to_reg) { int regno; unsigned int return_value; unsigned int var_size; unsigned int args_size; unsigned int pretend_size; unsigned int reg_size; unsigned int gmask; var_size = WORD_ALIGN (get_frame_size ()); args_size = WORD_ALIGN (current_function_outgoing_args_size); pretend_size = current_function_pretend_args_size; reg_size = 0; gmask = 0; /* Calculate space needed for registers. */ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno ++) { if (MUST_SAVE_REGISTER (regno)) { reg_size += UNITS_PER_WORD; gmask |= 1 << regno; } } current_frame_info.save_fp = MUST_SAVE_FRAME_POINTER; current_frame_info.save_rp = MUST_SAVE_RETURN_POINTER; reg_size += (current_frame_info.save_fp + current_frame_info.save_rp) * UNITS_PER_WORD; /* Save computed information. */ current_frame_info.pretend_size = pretend_size; current_frame_info.var_size = var_size; current_frame_info.args_size = args_size; current_frame_info.reg_size = reg_size; current_frame_info.frame_size = args_size + var_size; current_frame_info.total_size = args_size + var_size + reg_size + pretend_size; current_frame_info.gmask = gmask; current_frame_info.initialised = reload_completed; /* Calculate the required distance. */ return_value = 0; if (to_reg == STACK_POINTER_REGNUM) return_value += args_size + var_size; if (from_reg == ARG_POINTER_REGNUM) return_value += reg_size; return return_value; }
bool comm_msg_put_str(comm_msg_t *msg, const char *str) { uint32_t size = strlen(str) + 1; uint32_t aligned_size = WORD_ALIGN(size); uint32_t pad_size = aligned_size - size; if (!comm_msg_grow(msg, aligned_size + sizeof(size))) return false; /* Pack the size. */ comm_msg_put_u32(msg, aligned_size); /* Pack the data. */ memcpy(msg->buf + msg->used, str, size); msg->used += size; if (pad_size) { /* Add padding, if needed. */ memset(msg->buf + msg->used, 0, pad_size); msg->used += pad_size; } return true; }
CMemChunk* CMemChunk::New ( CChunkAllocator& aAllocator, RChunkPool& aChunkPool, TInt aNumBlocks , TInt aBlockSize ) { // allocates chunk on shared Heap using ::new operator // round of RMemCell & aBlockSize to the nearest word size. TInt memCellSize = WORD_ALIGN ( sizeof ( RMemCell ) ); TInt blockSize = WORD_ALIGN ( aBlockSize ); CMemChunk* chunk = new ( aNumBlocks * ( memCellSize + blockSize ), aAllocator ) CMemChunk ( aAllocator, aNumBlocks ); // In the complete memory allocated on shared heap; first bytes are of CMemChunk, // then start the memory required for RMemCell * NumBlocks and at the end contains // the actual data buffer. if ( chunk != NULL ) { // memory required for CMemChunk and for its parameters storage TUint8* chunkSize = ( ( TUint8* ) chunk ) + sizeof ( CMemChunk ); __ASSERT_DEBUG ( IS_WORD_ALIGNED ( chunkSize ), User::Invariant () ); // TODO Proper panic code // memory required for RMemCell and its parameters storage TUint8* dataBufStart = chunkSize + ( aNumBlocks * memCellSize ); // now place each RMemCell and its databuffer in the address specified for ( TInt i = 0; i < aNumBlocks ; i++ ) { // address assigned for RMemCell 'i' RMemCell* hdr = ( RMemCell* ) ( chunkSize + i * memCellSize ); // overloaded ::new, that makes in-place allocation of MemCell at specified address ( void ) new ( hdr ) RMemCell ( &aChunkPool, dataBufStart + ( i * aBlockSize ), aBlockSize ); // completed construction of a RMemCell. chunk->iQueue.Append ( hdr ); } } return chunk; }
// returns error code on failure static int copyinargs(const_userptr_t argv, char **kargv, size_t *argc_ret, size_t *total_len) { int err; size_t argc; // reserve space for arg pointers (and null-terminator) userptr_t *uargv = kmalloc((ARGNUM_MAX + 1) * sizeof(userptr_t)); // try to copy the argv array err = copyinwordstr(argv, (uintptr_t *)uargv, ARGNUM_MAX + 1, &argc); if (err) { kfree(uargv); return err; } // discount null-terminator from argc argc -= 1; // allocate space for the arguments themselves char *kargs = (char *)kmalloc(ARG_MAX * sizeof(char)); // keep track of our position in kargs char *kargs_cur = kargs; // copy in each argument string for (size_t i = 0; i < argc; i++) { // check bounds if (kargs_cur - kargs >= ARG_MAX) { kfree(uargv); kfree(kargs); return E2BIG; } // actually perform the copy and record the length // (including the null-terminator) size_t arg_len; err = copyinstr(uargv[i], kargs_cur, ARG_MAX, &arg_len); if (err) { kfree(uargv); kfree(kargs); if (err == ENAMETOOLONG) return E2BIG; else return err; } // set the entry in kargv to point to the // copied-in string kargv[i] = kargs_cur; // move on to the next string, padding properly kargs_cur += arg_len; char *kargs_cur_padded = (char *)WORD_ALIGN((uintptr_t)kargs_cur); while (kargs_cur < kargs_cur_padded) { *kargs_cur = 0; kargs_cur++; } } kfree(uargv); *argc_ret = argc; *total_len = kargs_cur - kargs; return 0; }
void run_process(void *ptr, unsigned long num) { (void)num; int result; vaddr_t entrypoint, stackptr; // extract and free passed-in context struct new_process_context *ctxt = (struct new_process_context *)ptr; struct process *proc = ctxt->proc; struct vnode *v = ctxt->executable; int nargs = ctxt->nargs; char **args = ctxt->args; kfree(ctxt); // attach process to thread curthread->t_proc = proc; proc->ps_thread = curthread; // Activate address space as_activate(proc->ps_addrspace); // Load the executable result = load_elf(v, &entrypoint); if (result) { vfs_close(v); kprintf("runprogram failed: %s\n", strerror(result)); // alert the kernel menu that the process aborted process_finish(proc, _MKWAIT_SIG(SIGABRT)); return; } // Done with the file now vfs_close(v); // Define the user stack in the address space result = as_define_stack(proc->ps_addrspace, &stackptr); if (result) { kprintf("runprogram failed: %s\n", strerror(result)); // alert the kernel menu that the process aborted process_finish(proc, _MKWAIT_SIG(SIGABRT)); return; } // Copy out arguments userptr_t uargv[nargs + 1]; for (int i = 0; i < nargs; i++) { int aligned_length = WORD_ALIGN(strlen(args[i]) + 1); stackptr -= aligned_length; uargv[i] = (userptr_t)stackptr; size_t arg_len; result = copyoutstr(args[i], uargv[i], strlen(args[i]) + 1, &arg_len); if (result) { kprintf("runprogram failed: %s\n", strerror(result)); // alert the kernel menu that the process aborted process_finish(proc, _MKWAIT_SIG(SIGABRT)); return; } } uargv[nargs] =(userptr_t)NULL; // Copy out the argv array itself stackptr -= (nargs + 1) * sizeof(userptr_t); result = copyout(uargv, (userptr_t)stackptr, (nargs + 1) * sizeof(userptr_t)); if (result) { kprintf("runprogram failed: %s\n", strerror(result)); // alert the kernel menu that the process aborted process_finish(proc, _MKWAIT_SIG(SIGABRT)); return; } enter_new_process(nargs, (userptr_t)stackptr, stackptr, entrypoint); // enter_new_process() does not return panic("enter_new_process returned\n"); }
status_t TiffWriter::write(Output* out, StripSource** sources, size_t sourcesCount, Endianness end) { status_t ret = OK; EndianOutput endOut(out, end); if (mIfd == NULL) { ALOGE("%s: Tiff header is empty.", __FUNCTION__); return BAD_VALUE; } uint32_t totalSize = getTotalSize(); KeyedVector<uint32_t, uint32_t> offsetVector; for (size_t i = 0; i < mNamedIfds.size(); ++i) { if (mNamedIfds[i]->uninitializedOffsets()) { uint32_t stripSize = mNamedIfds[i]->getStripSize(); if (mNamedIfds[i]->setStripOffset(totalSize) != OK) { ALOGE("%s: Could not set strip offsets.", __FUNCTION__); return BAD_VALUE; } totalSize += stripSize; WORD_ALIGN(totalSize); offsetVector.add(mNamedIfds.keyAt(i), totalSize); } } size_t offVecSize = offsetVector.size(); if (offVecSize != sourcesCount) { ALOGE("%s: Mismatch between number of IFDs with uninitialized strips (%zu) and" " sources (%zu).", __FUNCTION__, offVecSize, sourcesCount); return BAD_VALUE; } BAIL_ON_FAIL(writeFileHeader(endOut), ret); uint32_t offset = FILE_HEADER_SIZE; sp<TiffIfd> ifd = mIfd; while(ifd != NULL) { BAIL_ON_FAIL(ifd->writeData(offset, &endOut), ret); offset += ifd->getSize(); ifd = ifd->getNextIfd(); } if (LOG_NDEBUG == 0) { log(); } for (size_t i = 0; i < offVecSize; ++i) { uint32_t ifdKey = offsetVector.keyAt(i); uint32_t sizeToWrite = mNamedIfds[ifdKey]->getStripSize(); bool found = false; for (size_t j = 0; j < sourcesCount; ++j) { if (sources[j]->getIfd() == ifdKey) { if ((ret = sources[i]->writeToStream(endOut, sizeToWrite)) != OK) { ALOGE("%s: Could not write to stream, received %d.", __FUNCTION__, ret); return ret; } ZERO_TILL_WORD(&endOut, sizeToWrite, ret); found = true; break; } } if (!found) { ALOGE("%s: No stream for byte strips for IFD %u", __FUNCTION__, ifdKey); return BAD_VALUE; } assert(offsetVector[i] == endOut.getCurrentOffset()); } return ret; }