void VectorImpl::_shrink(size_t where, size_t amount) { if (!mStorage) return; // ALOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d", // this, (int)where, (int)amount, (int)mCount, (int)capacity()); ALOG_ASSERT(where + amount <= mCount, "[%p] _shrink: where=%d, amount=%d, count=%d", this, (int)where, (int)amount, (int)mCount); // caller already checked const size_t new_size = mCount - amount; if (new_size*3 < capacity()) { const size_t new_capacity = max(kMinVectorCapacity, new_size*2); // ALOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity); if ((where == new_size) && (mFlags & HAS_TRIVIAL_COPY) && (mFlags & HAS_TRIVIAL_DTOR)) { const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage); SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); if (sb) { mStorage = sb->data(); } else { return; } } else { SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); if (sb) { void* array = sb->data(); if (where != 0) { _do_copy(array, mStorage, where); } if (where != new_size) { const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize; void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize; _do_copy(dest, from, new_size - where); } release_storage(); mStorage = const_cast<void*>(array); } else{ return; } } } else { void* array = editArrayImpl(); void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize; _do_destroy(to, amount); if (where != new_size) { const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; _do_move_backward(to, from, new_size - where); } } mCount = new_size; }
void* VectorImpl::_grow(size_t where, size_t amount) { // ALOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d", // this, (int)where, (int)amount, (int)mCount, (int)capacity()); ALOG_ASSERT(where <= mCount, "[%p] _grow: where=%d, amount=%d, count=%d", this, (int)where, (int)amount, (int)mCount); // caller already checked const size_t new_size = mCount + amount; if (capacity() < new_size) { const size_t new_capacity = max(kMinVectorCapacity, ((new_size*3)+1)/2); // ALOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity); if ((mStorage) && (mCount==where) && (mFlags & HAS_TRIVIAL_COPY) && (mFlags & HAS_TRIVIAL_DTOR)) { const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage); SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); if (sb) { mStorage = sb->data(); } else { return NULL; } } else { SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); if (sb) { void* array = sb->data(); if (where != 0) { _do_copy(array, mStorage, where); } if (where != mCount) { const void* from = reinterpret_cast<const uint8_t *>(mStorage) + where*mItemSize; void* dest = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; _do_copy(dest, from, mCount-where); } release_storage(); mStorage = const_cast<void*>(array); } else { return NULL; } } } else { void* array = editArrayImpl(); if (where != mCount) { const void* from = reinterpret_cast<const uint8_t *>(array) + where*mItemSize; void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; _do_move_forward(to, from, mCount - where); } } mCount = new_size; void* free_space = const_cast<void*>(itemLocation(where)); return free_space; }
void VectorImpl::_shrink(size_t where, size_t amount) { if (!mStorage) return; // LOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d", // this, (int)where, (int)amount, (int)mCount, (int)capacity()); if (where >= mCount) where = mCount - amount; const size_t new_size = mCount - amount; if (new_size*3 < capacity()) { const size_t new_capacity = max(kMinVectorCapacity, new_size*2); // LOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity); if ((where == mCount-amount) && (mFlags & HAS_TRIVIAL_COPY) && (mFlags & HAS_TRIVIAL_DTOR)) { const SharedBuffer* cur_sb = SharedBuffer::sharedBuffer(mStorage); SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); mStorage = sb->data(); } else { SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); if (sb) { void* array = sb->data(); if (where>0) { _do_copy(array, mStorage, where); } if (mCount > where+amount) { const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize; void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize; _do_copy(dest, from, mCount-(where+amount)); } release_storage(); mStorage = const_cast<void*>(array); } } } else { void* array = editArrayImpl(); void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize; _do_destroy(to, amount); ssize_t s = mCount-(where+amount); if (s>0) { const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; _do_move_backward(to, from, s); } } // adjust the number of items... mCount -= amount; }
void press_button_to_reboot() { s32 pressed = 0; while (1) { WPAD_ScanPads(); pressed = WPAD_ButtonsDown(0); if (pressed) { release_storage(); SYS_ResetSystem(SYS_RESTART,0,0); } } }
void* VectorImpl::editArrayImpl() { if (mStorage) { SharedBuffer* sb = SharedBuffer::bufferFromData(mStorage)->attemptEdit(); if (sb == 0) { sb = SharedBuffer::alloc(capacity() * mItemSize); if (sb) { _do_copy(sb->data(), mStorage, mCount); release_storage(); mStorage = sb->data(); } } } return mStorage; }
VectorImpl& VectorImpl::operator = (const VectorImpl& rhs) { LOG_ALWAYS_FATAL_IF(mItemSize != rhs.mItemSize, "Vector<> have different types (this=%p, rhs=%p)", this, &rhs); if (this != &rhs) { release_storage(); if (rhs.mCount) { mStorage = rhs.mStorage; mCount = rhs.mCount; SharedBuffer::bufferFromData(mStorage)->acquire(); } else { mStorage = 0; mCount = 0; } } return *this; }
VectorImpl& VectorImpl::operator = (const VectorImpl& rhs) { ALOG_ASSERT(mItemSize == rhs.mItemSize, "Vector<> have different types (this=%p, rhs=%p)", this, &rhs); if (this != &rhs) { release_storage(); if (rhs.mCount) { mStorage = rhs.mStorage; mCount = rhs.mCount; SharedBuffer::sharedBuffer(mStorage)->acquire(); } else { mStorage = 0; mCount = 0; } } return *this; }
ssize_t VectorImpl::setCapacity(size_t new_capacity) { size_t current_capacity = capacity(); ssize_t amount = new_capacity - size(); if (amount <= 0) { // we can't reduce the capacity return current_capacity; } SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); if (sb) { void* array = sb->data(); _do_copy(array, mStorage, size()); release_storage(); mStorage = const_cast<void*>(array); } else { return NO_MEMORY; } return new_capacity; }
void* VectorImpl::editArrayImpl() { if (mStorage) { const SharedBuffer* sb = SharedBuffer::bufferFromData(mStorage); SharedBuffer* editable = sb->attemptEdit(); if (editable == 0) { // If we're here, we're not the only owner of the buffer. // We must make a copy of it. editable = SharedBuffer::alloc(sb->size()); // Fail instead of returning a pointer to storage that's not // editable. Otherwise we'd be editing the contents of a buffer // for which we're not the only owner, which is undefined behaviour. LOG_ALWAYS_FATAL_IF(editable == NULL); _do_copy(editable->data(), mStorage, mCount); release_storage(); mStorage = editable->data(); } } return mStorage; }
ssize_t VectorImpl::setCapacity(size_t new_capacity) { // The capacity must always be greater than or equal to the size // of this vector. if (new_capacity <= size()) { return capacity(); } size_t new_allocation_size = 0; LOG_ALWAYS_FATAL_IF(!safe_mul(&new_allocation_size, new_capacity, mItemSize)); SharedBuffer* sb = SharedBuffer::alloc(new_allocation_size); if (sb) { void* array = sb->data(); _do_copy(array, mStorage, size()); release_storage(); mStorage = const_cast<void*>(array); } else { return NO_MEMORY; } return new_capacity; }
void VectorImpl::finish_vector() { release_storage(); mStorage = 0; mCount = 0; }
void VectorImpl::_shrink(size_t where, size_t amount) { if (!mStorage) return; // ALOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d", // this, (int)where, (int)amount, (int)mCount, (int)capacity()); ALOG_ASSERT(where + amount <= mCount, "[%p] _shrink: where=%d, amount=%d, count=%d", this, (int)where, (int)amount, (int)mCount); // caller already checked size_t new_size; LOG_ALWAYS_FATAL_IF(!safe_sub(&new_size, mCount, amount)); if (new_size < (capacity() / 2)) { // NOTE: (new_size * 2) is safe because capacity didn't overflow and // new_size < (capacity / 2)). const size_t new_capacity = max(kMinVectorCapacity, new_size * 2); // NOTE: (new_capacity * mItemSize), (where * mItemSize) and // ((where + amount) * mItemSize) beyond this point are safe because // we are always reducing the capacity of the underlying SharedBuffer. // In other words, (old_capacity * mItemSize) did not overflow, and // where < (where + amount) < new_capacity < old_capacity. if ((where == new_size) && (mFlags & HAS_TRIVIAL_COPY) && (mFlags & HAS_TRIVIAL_DTOR)) { const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage); SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); if (sb) { mStorage = sb->data(); } else { return; } } else { SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); if (sb) { void* array = sb->data(); if (where != 0) { _do_copy(array, mStorage, where); } if (where != new_size) { const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize; void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize; _do_copy(dest, from, new_size - where); } release_storage(); mStorage = const_cast<void*>(array); } else{ return; } } } else { void* array = editArrayImpl(); void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize; _do_destroy(to, amount); if (where != new_size) { const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; _do_move_backward(to, from, new_size - where); } } mCount = new_size; }
void* VectorImpl::_grow(size_t where, size_t amount) { // ALOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d", // this, (int)where, (int)amount, (int)mCount, (int)capacity()); ALOG_ASSERT(where <= mCount, "[%p] _grow: where=%d, amount=%d, count=%d", this, (int)where, (int)amount, (int)mCount); // caller already checked size_t new_size; LOG_ALWAYS_FATAL_IF(!safe_add(&new_size, mCount, amount), "new_size overflow"); if (capacity() < new_size) { // NOTE: This implementation used to resize vectors as per ((3*x + 1) / 2) // (sigh..). Also note, the " + 1" was necessary to handle the special case // where x == 1, where the resized_capacity will be equal to the old // capacity without the +1. The old calculation wouldn't work properly // if x was zero. // // This approximates the old calculation, using (x + (x/2) + 1) instead. size_t new_capacity = 0; LOG_ALWAYS_FATAL_IF(!safe_add(&new_capacity, new_size, (new_size / 2)), "new_capacity overflow"); LOG_ALWAYS_FATAL_IF(!safe_add(&new_capacity, new_capacity, static_cast<size_t>(1u)), "new_capacity overflow"); new_capacity = max(kMinVectorCapacity, new_capacity); size_t new_alloc_size = 0; LOG_ALWAYS_FATAL_IF(!safe_mul(&new_alloc_size, new_capacity, mItemSize), "new_alloc_size overflow"); // ALOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity); if ((mStorage) && (mCount==where) && (mFlags & HAS_TRIVIAL_COPY) && (mFlags & HAS_TRIVIAL_DTOR)) { const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage); SharedBuffer* sb = cur_sb->editResize(new_alloc_size); if (sb) { mStorage = sb->data(); } else { return NULL; } } else { SharedBuffer* sb = SharedBuffer::alloc(new_alloc_size); if (sb) { void* array = sb->data(); if (where != 0) { _do_copy(array, mStorage, where); } if (where != mCount) { const void* from = reinterpret_cast<const uint8_t *>(mStorage) + where*mItemSize; void* dest = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; _do_copy(dest, from, mCount-where); } release_storage(); mStorage = const_cast<void*>(array); } else { return NULL; } } } else { void* array = editArrayImpl(); if (where != mCount) { const void* from = reinterpret_cast<const uint8_t *>(array) + where*mItemSize; void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; _do_move_forward(to, from, mCount - where); } } mCount = new_size; void* free_space = const_cast<void*>(itemLocation(where)); return free_space; }
//--------------------------------------------------------------------------------- int main(int argc, char **argv) { //--------------------------------------------------------------------------------- #ifdef DEBUG init_video_and_wpad(); printf("::: Configurable USB Loader - Forwarder Universal [SD/USB] by Narolez :::\n\n"); #endif // create a buffer for the elf/dol content void* myBuffer; // read elf/dol from given path: FILE* inputFile; // try loading from SD inputFile = tryOpenDolFromSD(); // dol file on SD not found if(inputFile == NULL) { // try loading from USB inputFile = tryOpenDolFromUSB(); } // dol file on SD or USB not found if(inputFile == NULL) { init_video_and_wpad(); printf("\nError: Couldn't open file!\n"); printf("Press any button to reboot Wii...\n"); press_button_to_reboot(); } #ifdef DEBUG printf("\n[+] Loading %s to buffer ... ", filename); #endif int pos = ftell(inputFile); fseek(inputFile, 0, SEEK_END); int size = ftell(inputFile); fseek(inputFile, pos, SEEK_SET); //return to previous position myBuffer = malloc(size); fread( myBuffer, 1, size, inputFile); fclose(inputFile); #ifdef DEBUG printf("OK!\n"); #endif release_storage(); #ifdef DEBUG printf("\n[+] Running ... "); #endif //Check if valid elf file: s32 res; res = valid_elf_image(myBuffer); if(res == 1) { //elf ok! -> Load entry point of elf file: void (*ep)(); ep = (void(*)())load_elf_image(myBuffer); // code from geckoloader u32 level; __IOS_ShutdownSubsystems (); //printf("IOS_ShutdownSubsystems() done\n"); _CPU_ISR_Disable (level); //printf("_CPU_ISR_Disable() done\n"); __exception_closeall (); //printf("__exception_closeall() done. Jumping to ep now...\n"); ep(); _CPU_ISR_Restore (level); } else { //Elf not valid, load dol: //Stuff for arguments struct __argv argv; bzero(&argv, sizeof(argv)); argv.argvMagic = ARGV_MAGIC; argv.length = strlen(filename) + 2; argv.commandLine = malloc(argv.length); if (!argv.commandLine) { init_video_and_wpad(); printf("Error creating arguments, could not allocate memory for commandLine\n"); printf("Press any button to reboot Wii...\n"); press_button_to_reboot(); } strcpy(argv.commandLine, filename); argv.commandLine[argv.length - 1] = '\x00'; argv.argc = 1; argv.argv = &argv.commandLine; argv.endARGV = argv.argv + 1; run_dol(myBuffer, &argv); } #ifdef DEBUG printf("HAVE FUN!"); #endif return 0; }