From 8864a55a720e435c41b08b844fd85cdc3cd64ae2 Mon Sep 17 00:00:00 2001 From: Maschell Date: Sun, 10 Sep 2017 22:02:19 +0200 Subject: [PATCH] Added libntfs support and changed the progress format - added libntfs support via (https://github.com/Maschell/libntfs-wiiu). When dumping to a ntfs device creating the hash will be disabled because of crashes. - updated dynamic libs (and added them as a submodule) - added logging --- .gitignore | 13 + .gitmodules | 3 + Makefile | 17 +- README.md | 19 +- include/stdint.h | 15 -- src/dynamic_libs | 1 + src/main.cpp | 562 ++++++++++++++++++++++++++++++++++++++++++++ src/system/memory.c | 67 ++++-- src/system/memory.h | 6 +- src/utils/logger.c | 76 ++++++ src/utils/logger.h | 32 +++ 11 files changed, 759 insertions(+), 52 deletions(-) create mode 100644 .gitignore create mode 100644 .gitmodules delete mode 100644 include/stdint.h create mode 160000 src/dynamic_libs create mode 100644 src/main.cpp create mode 100644 src/utils/logger.c create mode 100644 src/utils/logger.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ec7e40d --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +*.o +*.elf +*.d +build/.map +payload/* +arm_kernel/arm_kernel.bin +arm_kernel/arm_kernel_bin.h +arm_user/arm_user.bin +arm_user/arm_user_bin.h +odmhook/odmhook.bin +odmhook/odmhook_bin.h +wupserver/wupserver.bin +wupserver/wupserver_bin.h \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..5b6b6a9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/dynamic_libs"] + path = src/dynamic_libs + url = https://github.com/Maschell/dynamic_libs diff --git a/Makefile b/Makefile index 0b9d6b5..4e29383 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,8 @@ SOURCES := src \ src/fs \ src/system \ src/utils \ - src/polarssl + src/polarssl \ + src/utils DATA := INCLUDES := src include payload @@ -45,9 +46,9 @@ INCLUDES := src include payload # options for code generation #--------------------------------------------------------------------------------- CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ - -O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) + -D__wiiu__ -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing -D_GNU_SOURCE $(INCLUDE) CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ - -O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) + -D__wiiu__ -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing -D_GNU_SOURCE $(INCLUDE) ASFLAGS := -mregnames LDFLAGS := -nostartfiles -Wl,-Map,$(notdir $@).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r,-wrap,valloc,-wrap,_valloc_r,-wrap,_pvalloc_r,--gc-sections @@ -57,14 +58,15 @@ MAKEFLAGS += --no-print-directory #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -lfat -liosuhax +LIBS := -lm -lgcc -lfat -lntfs -liosuhax #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- LIBDIRS := $(CURDIR) \ - $(DEVKITPPC)/lib + $(DEVKITPPC)/lib \ + $(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2 #--------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional @@ -105,14 +107,15 @@ export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ #--------------------------------------------------------------------------------- export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(PORTLIBS)/include -I$(PORTLIBS)/include/freetype2 \ -I$(CURDIR)/$(BUILD) -I$(LIBOGC_INC) \ - -I$(PORTLIBS)/include -I$(PORTLIBS)/include/freetype2 + #--------------------------------------------------------------------------------- # build a list of library paths #--------------------------------------------------------------------------------- export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ - -L$(LIBOGC_LIB) -L$(PORTLIBS)/lib + -L$(PORTLIBS)/lib export OUTPUT := $(CURDIR)/$(TARGET) .PHONY: $(BUILD) clean install diff --git a/README.md b/README.md index d4f7669..caae997 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,22 @@ # wudump dump raw images from a wiiu game disc # Usage -Download and run the .elf from homebrew launcher with a fat32 sd card/usb device inserted that has at least 23.3gb free. -The files will be dumped in 2gb parts, you will have to merge them yourself afterwards if you need the full game.wud. +Download and run the .elf from homebrew launcher with a fat32 sd card/usb device or NTFS usb device inserted that has at least 23.3gb free. +On fat32 devices the files will be dumped in 2gb parts, you will have to merge them yourself afterwards if you need the full game.wud. On NTFS devices it will be dumped into a single file. + A full dump can take a little over one and a half hours. -After it has been dumped the wud parts, common.key and game.key will be in a "wudump" folder on your sd card/usb device, to get the full game.wud you will have to merge them. +After it has been dumped the wud, common.key and game.key will be in a "wudump" folder on your sd card/usb device. + +## Merging the wud parts on FAT32 devices. +This step is not needed, when the file was dumped to a ntfs device. + +To get the full game.wud with FAT32 devices you will have to merge them. If you are on windows you can use something like this for example to merge them into a game.wud on a "wudump" folder on your C drive from a cmd in the sd/usb folder: ``` copy /b game_part1.wud + game_part2.wud + game_part3.wud + game_part4.wud + game_part5.wud + game_part6.wud + game_part7.wud + game_part8.wud + game_part9.wud + game_part10.wud + game_part11.wud + game_part12.wud C:\wudump\game.wud ``` +## wud2app If you would just like to install your game using wupinstaller then grab wud2app: https://github.com/FIX94/wud2app/releases If you dont want to merge all .wud files you can put wud2app into a folder on your pc and run it from a cmd with the wudump folder path as argument, for example if the sd/usb folder happens to be in "P:\wudump\WUP-P-TEST" on windows you can just run wud2app like: @@ -23,3 +30,9 @@ wud2app common.key game.key game.wud Make sure to copy the common.key and game.key into that folder as well if you use that method. The folder it creates can just be installed by wupinstaller. + +# Build +For building you need: +- [libfat](https://github.com/aliaspider/libfat/) +- [libiosuhax](https://github.com/dimok789/libiosuhax) (Build WITHOUT the WUT flag set.) +- [libntfs](https://github.com/Maschell/libntfs-wiiu) (Build with make wiiu-install) \ No newline at end of file diff --git a/include/stdint.h b/include/stdint.h deleted file mode 100644 index fff483d..0000000 --- a/include/stdint.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _STDINT_WRAP_H -#define _STDINT_WRAP_H - -#define int32_t dontcare_int32_t -#define uint32_t dontcare_uint32_t - -#include_next - -#undef int32_t -#undef uint32_t - -typedef signed int int32_t; -typedef unsigned int uint32_t; - -#endif \ No newline at end of file diff --git a/src/dynamic_libs b/src/dynamic_libs new file mode 160000 index 0000000..451c406 --- /dev/null +++ b/src/dynamic_libs @@ -0,0 +1 @@ +Subproject commit 451c406012c2bdf1fe8489583e685afa2fdb1dd6 diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..8e002ed --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,562 @@ +/* + * Copyright (C) 2016-2017 FIX94 + * + * This software may be modified and distributed under the terms + * of the MIT license. See the LICENSE file for details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dynamic_libs/os_types.h" +#include "dynamic_libs/os_functions.h" +#include "dynamic_libs/socket_functions.h" +#include "dynamic_libs/sys_functions.h" +#include "dynamic_libs/vpad_functions.h" +#include "system/memory.h" +#include "common/common.h" +#include "main.h" +#include "exploit.h" +#include "utils/logger.h" +#include "../payload/wupserver_bin.h" + +//just to be able to call async +void someFunc(void *arg) +{ + (void)arg; +} + +static int mcp_hook_fd = -1; +int MCPHookOpen() +{ + //take over mcp thread + mcp_hook_fd = MCP_Open(); + if(mcp_hook_fd < 0) + return -1; + IOS_IoctlAsync(mcp_hook_fd, 0x62, (void*)0, 0, (void*)0, 0, (void*)someFunc, (void*)0); + //let wupserver start up + os_sleep(1); + if(IOSUHAX_Open("/dev/mcp") < 0) + return -1; + return 0; +} + +void MCPHookClose() +{ + if(mcp_hook_fd < 0) + return; + //close down wupserver, return control to mcp + IOSUHAX_Close(); + //wait for mcp to return + os_sleep(1); + MCP_Close(mcp_hook_fd); + mcp_hook_fd = -1; +} + +void println_noflip(int line, const char *msg) +{ + OSScreenPutFontEx(0,0,line,msg); + OSScreenPutFontEx(1,0,line,msg); +} + +void println(int line, const char *msg) +{ + int i; + for(i = 0; i < 2; i++) + { //double-buffered font write + println_noflip(line,msg); + OSScreenFlipBuffersEx(0); + OSScreenFlipBuffersEx(1); + } +} + +#define SECTOR_SIZE 2048 +#define NUM_SECTORS 1024 + +int fsa_odd_read(int fsa_fd, int fd, void *buf, int offset){ + return IOSUHAX_FSA_RawRead(fsa_fd, buf, SECTOR_SIZE, NUM_SECTORS, offset, fd); +} + +int fsa_write(int fsa_fd, int fd, void *buf, int len){ + int done = 0; + uint8_t *buf_u8 = (uint8_t*)buf; + while(done < len) + { + size_t write_size = len - done; + int result = IOSUHAX_FSA_WriteFile(fsa_fd, buf_u8 + done, 0x01, write_size, fd, 0); + if(result < 0) + return result; + else + done += result; + } + return done; +} + +static const char *hdrStr = "wudump v1.6 by FIX94"; +void printhdr_noflip(){ + println_noflip(0,hdrStr); +} + +void write_hash_file(char *fName, char *dir, unsigned int crc32, md5_context *md5ctx, sha1_context *sha1ctx){ + unsigned int md5[4]; + md5_finish(md5ctx, (unsigned char*)md5); + unsigned int sha1[5]; + sha1_finish(sha1ctx, (unsigned char*)sha1); + + char wudPath[64]; + sprintf(wudPath, "%s/%s.txt", dir, fName); + FILE *f = fopen(wudPath, "w"); + if(f) + { + fprintf(f, "%s\n\n", hdrStr); + fprintf(f, "Hashes for %s.wud:\n", fName); + fprintf(f, "CRC32: %08X\n" + "MD5: %08X%08X%08X%08X\n" + "SHA1: %08X%08X%08X%08X%08X\n", + crc32, md5[0],md5[1],md5[2],md5[3], + sha1[0],sha1[1],sha1[2],sha1[3],sha1[4]); + fclose(f); + f = NULL; + } +} + +//imported OS zlib crc32 function pointer +static unsigned int (*zlib_crc32)(unsigned int crc32, const void *buf, int bufsize) = (unsigned int (*)(unsigned int, const void*, int))0; + +static const int bufSize = SECTOR_SIZE*NUM_SECTORS; +static void *sectorBuf = NULL; +static bool threadRunning = true; +static unsigned int crc32Val = 0; +static md5_context md5ctx; +static sha1_context sha1ctx; +static unsigned int crc32PartVal = 0; +static md5_context md5PartCtx; +static sha1_context sha1PartCtx; + +static s32 hashThread(s32 argc, void *args){ + (void)argc; + (void)args; + while(threadRunning) { + //update global hashes + crc32Val = zlib_crc32(crc32Val, sectorBuf, bufSize); + md5_update(&md5ctx, (const unsigned char *) sectorBuf, bufSize); + sha1_update(&sha1ctx, (const unsigned char *)sectorBuf, bufSize); + //update hashes for part file + crc32PartVal = zlib_crc32(crc32PartVal, (const unsigned char *)sectorBuf, bufSize); + md5_update(&md5PartCtx, (const unsigned char *)sectorBuf, bufSize); + sha1_update(&sha1PartCtx, (const unsigned char *)sectorBuf, bufSize); + //go back to os_sleep + OSSuspendThread(OSGetCurrentThread()); + } + return 0; +} + +int Menu_Main(void){ + InitOSFunctionPointers(); + InitSocketFunctionPointers(); + + log_init(); + + InitSysFunctionPointers(); + InitVPadFunctionPointers(); + u32 zlib_handle = 0; + OSDynLoad_Acquire("zlib125.rpl", &zlib_handle); + OSDynLoad_FindExport(zlib_handle, 0, "crc32", &zlib_crc32); + VPADInit(); + memoryInitialize(); + + // Init screen + OSScreenInit(); + int screen_buf0_size = OSScreenGetBufferSizeEx(0); + int screen_buf1_size = OSScreenGetBufferSizeEx(1); + uint8_t *screenBuffer = (uint8_t*)MEMBucket_alloc(screen_buf0_size+screen_buf1_size, 0x100); + OSScreenSetBufferEx(0, screenBuffer); + OSScreenSetBufferEx(1, (screenBuffer + screen_buf0_size)); + OSScreenEnableEx(0, 1); + OSScreenEnableEx(1, 1); + OSScreenClearBufferEx(0, 0); + OSScreenClearBufferEx(1, 0); + + printhdr_noflip(); + println_noflip(2,"Please make sure to take out any currently inserted disc."); + println_noflip(3,"Also make sure you have at least 23.3GB free on your device."); + println_noflip(4,"Press A to continue with a FAT32 SD Card as destination."); + println_noflip(5,"Press B to continue with a FAT32 USB Device as destination."); + println_noflip(6,"Press X to continue with a NTFS USB Device as destination."); + println_noflip(7,"Press HOME to return to the Homebrew Launcher."); + OSScreenFlipBuffersEx(0); + OSScreenFlipBuffersEx(1); + + s32 vpadError = -1; + VPADData vpad; + int action = 0; + while(1) + { + VPADRead(0, &vpad, 1, &vpadError); + if(vpadError == 0) + { + if((vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_HOME) + { + MEMBucket_free(screenBuffer); + memoryRelease(); + return EXIT_SUCCESS; + } + else if((vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_A) + break; + else if((vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_B) + { + action = 1; + break; + }else if((vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_X) + { + action = 2; + break; + } + } + os_usleep(50000); + } + int j; + for(j = 0; j < 2; j++) + { + OSScreenClearBufferEx(0, 0); + OSScreenClearBufferEx(1, 0); + printhdr_noflip(); + OSScreenFlipBuffersEx(0); + OSScreenFlipBuffersEx(1); + os_usleep(25000); + } + int line = 2; + //will inject our custom mcp code + println(line++,"Doing IOSU Exploit..."); + *(volatile unsigned int*)0xF5E70000 = wupserver_bin_len; + memcpy((void*)0xF5E70020, &wupserver_bin, wupserver_bin_len); + DCStoreRange((void*)0xF5E70000, wupserver_bin_len + 0x40); + IOSUExploit(); + int fsaFd = -1; + int oddFd = -1; + s32 ret; + char wudumpPath[64]; + char wudPath[64]; + char keyPath[64]; + FILE *f = NULL; + + OSThread * thread = NULL; + void *stack = NULL; + int retry = 10; + + ntfs_md * ntfs_mounts = NULL; + int ntfs_mount_count = 0; + int useNTFS = 0; + + s32 apd_enabled = 0; + + bool newF = true; + int part = 0; + unsigned int readSectors = 0; + + //done with iosu exploit, take over mcp + if(MCPHookOpen() < 0) + { + println(line++,"MCP hook could not be opened!"); + goto prgEnd; + } + memset((void*)0xF5E10C00, 0, 0x20); + DCFlushRange((void*)0xF5E10C00, 0x20); + println(line++,"Done!"); + + //mount with full permissions + fsaFd = IOSUHAX_FSA_Open(); + if(fsaFd < 0) + { + println(line++,"FSA could not be opened!"); + goto prgEnd; + } + fatInitDefault(); + + println(line++,"Please insert the disc you want to dump now to begin."); + //wait for disc key to be written + while(1) + { + DCInvalidateRange((void*)0xF5E10C00, 0x20); + if(*(volatile unsigned int*)0xF5E10C00 != 0) + break; + VPADRead(0, &vpad, 1, &vpadError); + if(vpadError == 0) + { + if((vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_HOME) + goto prgEnd; + } + os_usleep(50000); + } + + //opening raw odd might take a bit + retry = 10; + ret = -1; + while(ret < 0) + { + ret = IOSUHAX_FSA_RawOpen(fsaFd, "/dev/odd01", &oddFd); + retry--; + if(retry < 0) + break; + os_sleep(1); + } + if(ret < 0) + { + println(line++,"Failed to open Raw ODD!"); + goto prgEnd; + } + + //get our 2MB I/O Buffer and read out first sector + sectorBuf = MEMBucket_alloc(bufSize, 0x100); + if(sectorBuf == NULL || fsa_odd_read(fsaFd, oddFd, sectorBuf, 0) < 0) + { + println(line++,"Failed to read first disc sector!"); + goto prgEnd; + } + + //get disc name for folder + char discId[11]; + discId[10] = '\0'; + memcpy(discId, sectorBuf, 10); + char discStr[64]; + sprintf(discStr, "Inserted %s", discId); + println(line++, discStr); + + // make wudump dir we will write to + char device[255]; + if(action == 0){ + sprintf(device, "%s", "sd:"); + }else if(action == 1){ + sprintf(device, "%s", "usb:"); + }else if(action == 2){ + ntfs_mount_count = ntfsMountAll((ntfs_md **) &ntfs_mounts, NTFS_DEFAULT | NTFS_RECOVER); + + // List all mounted NTFS volumes + + for (int i = 0; i < ntfs_mount_count; i++){ + useNTFS = 1; + sprintf(device, "%s:", ntfs_mounts[i].name); + break; + } + if(!useNTFS){ + println(line++,"Failed to open NTFS! No partition found!"); + goto prgEnd; + } + } + sprintf(wudumpPath, "%s/wudump", device); + mkdir(wudumpPath, 0x600); + sprintf(wudumpPath, "%s/wudump/%s", device, discId); + mkdir(wudumpPath, 0x600); + + u8 cKey[0x10]; + memcpy(cKey, (void*)0xF5E104E0, 0x10); + + sprintf(keyPath, "%s/common.key", wudumpPath); + f = fopen(keyPath, "wb"); + if(f == NULL) + { + println(line++,"Failed to write Common Key!"); + goto prgEnd; + } + fwrite(cKey, 1, 0x10, f); + fclose(f); + f = NULL; + println(line++,"Common Key dumped!"); + + u8 discKey[0x10]; + memcpy(discKey, (void*)0xF5E10C00, 0x10); + + sprintf(keyPath, "%s/game.key", wudumpPath); + f = fopen(keyPath, "wb"); + if(f == NULL) + { + println(line++,"Failed to write Disc Key!"); + goto prgEnd; + } + fwrite(discKey, 1, 0x10, f); + fclose(f); + f = NULL; + println(line++, "Disc Key dumped!"); + + apd_enabled = 0; + IMIsAPDEnabled(&apd_enabled); + if(apd_enabled) + { + if(IMDisableAPD() == 0) + println(line++, "Disabled Auto Power-Down."); + } + + sprintf(discStr, "Dumping %s...", discId); + char progress[64]; + newF = true; + part = 0; + readSectors = 0; + + //full hashes + + if(!useNTFS){ + crc32Val = 0; + md5_starts(&md5ctx); + sha1_starts(&sha1ctx); + + //part hashes + crc32PartVal = 0; + md5_starts(&md5PartCtx); + sha1_starts(&sha1PartCtx); + + //create hashing thread + + stack = MEMBucket_alloc(0x4000, 0x20); + thread = (OSThread*)memalign(8, 0x1000); //thread cant be in MEMBucket + OSCreateThread(thread, hashThread, 0, NULL, (u32)stack+0x4000, 0x4000, 20, (1<= 0) + { + if(f != NULL) + fclose(f); + fatUnmount("sd:"); + fatUnmount("usb:"); + + if (ntfs_mounts) { + int i = 0; + for (i = 0; i < ntfs_mount_count; i++){ + ntfsUnmount(ntfs_mounts[i].name, true); + } + free(ntfs_mounts); + ntfs_mounts = NULL; + ntfs_mount_count = 0; + } + + if(oddFd >= 0) + IOSUHAX_FSA_RawClose(fsaFd, oddFd); + IOSUHAX_FSA_Close(fsaFd); + if(sectorBuf != NULL) + MEMBucket_free(sectorBuf); + + + } + //close out old mcp instance + MCPHookClose(); + os_sleep(5); + //will do IOSU reboot + OSForceFullRelaunch(); + SYSLaunchMenu(); + OSScreenEnableEx(0, 0); + OSScreenEnableEx(1, 0); + MEMBucket_free(screenBuffer); + memoryRelease(); + return EXIT_RELAUNCH_ON_LOAD; +} diff --git a/src/system/memory.c b/src/system/memory.c index 91f5392..7cc7e0f 100644 --- a/src/system/memory.c +++ b/src/system/memory.c @@ -34,32 +34,32 @@ //! Memory functions //! This is the only place where those are needed so lets keep them more or less private //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -extern unsigned int * pMEMAllocFromDefaultHeapEx; -extern unsigned int * pMEMAllocFromDefaultHeap; -extern unsigned int * pMEMFreeToDefaultHeap; - -extern int (* MEMGetBaseHeapHandle)(int mem_arena); -extern unsigned int (* MEMGetAllocatableSizeForFrmHeapEx)(int heap, int align); -extern void *(* MEMAllocFromFrmHeapEx)(int heap, unsigned int size, int align); -extern void (* MEMFreeToFrmHeap)(int heap, int mode); -extern void *(* MEMAllocFromExpHeapEx)(int heap, unsigned int size, int align); -extern int (* MEMCreateExpHeapEx)(void* address, unsigned int size, unsigned short flags); -extern void *(* MEMDestroyExpHeap)(int heap); -extern void (* MEMFreeToExpHeap)(int heap, void* ptr); - -static int mem1_heap = -1; -static int bucket_heap = -1; +extern u32 * pMEMAllocFromDefaultHeapEx; +extern u32 * pMEMAllocFromDefaultHeap; +extern u32 * pMEMFreeToDefaultHeap; + +extern s32 (* MEMGetBaseHeapHandle)(s32 mem_arena); +extern u32 (* MEMGetAllocatableSizeForFrmHeapEx)(s32 heap, s32 align); +extern void *(* MEMAllocFromFrmHeapEx)(s32 heap, u32 size, s32 align); +extern void (* MEMFreeToFrmHeap)(s32 heap, s32 mode); +extern void *(* MEMAllocFromExpHeapEx)(s32 heap, u32 size, s32 align); +extern s32 (* MEMCreateExpHeapEx)(void* address, u32 size, unsigned short flags); +extern void *(* MEMDestroyExpHeap)(s32 heap); +extern void (* MEMFreeToExpHeap)(s32 heap, void* ptr); + +static s32 mem1_heap = -1; +static s32 bucket_heap = -1; void memoryInitialize(void) { - int mem1_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_1); - unsigned int mem1_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(mem1_heap_handle, 4); + s32 mem1_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_1); + u32 mem1_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(mem1_heap_handle, 4); void *mem1_memory = MEMAllocFromFrmHeapEx(mem1_heap_handle, mem1_allocatable_size, 4); if(mem1_memory) mem1_heap = MEMCreateExpHeapEx(mem1_memory, mem1_allocatable_size, 0); - int bucket_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET); - unsigned int bucket_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(bucket_heap_handle, 4); + s32 bucket_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET); + u32 bucket_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(bucket_heap_handle, 4); void *bucket_memory = MEMAllocFromFrmHeapEx(bucket_heap_handle, bucket_allocatable_size, 4); if(bucket_memory) bucket_heap = MEMCreateExpHeapEx(bucket_memory, bucket_allocatable_size, 0); @@ -116,8 +116,27 @@ size_t __wrap_malloc_usable_size(void *p) return 0x7FFFFFFF; } -void *__wrap_realloc(void *p, size_t size) +void *__wrap_realloc(void *ptr, size_t size) { + void *newPtr; + + if (!ptr) { + newPtr = __wrap_malloc(size); + if (!newPtr) { goto error; } + } else { + newPtr = __wrap_malloc(size); + if (!newPtr) { goto error; } + + memcpy(newPtr, ptr, size); + + __wrap_free(ptr); + } + + return newPtr; +error: + return NULL; +} + /* void *new_ptr = __wrap_malloc(size); if (new_ptr != 0) { @@ -125,7 +144,7 @@ void *__wrap_realloc(void *p, size_t size) __wrap_free(p); } return new_ptr; -} +}*/ //!------------------------------------------------------------------------------------------- //! reent versions @@ -163,7 +182,7 @@ void *__wrap__realloc_r(struct _reent *r, void *p, size_t size) //!------------------------------------------------------------------------------------------- //! some wrappers //!------------------------------------------------------------------------------------------- -void * MEM2_alloc(unsigned int size, unsigned int align) +void * MEM2_alloc(u32 size, u32 align) { return __wrap_memalign(align, size); } @@ -173,7 +192,7 @@ void MEM2_free(void *ptr) __wrap_free(ptr); } -void * MEM1_alloc(unsigned int size, unsigned int align) +void * MEM1_alloc(u32 size, u32 align) { if (align < 4) align = 4; @@ -185,7 +204,7 @@ void MEM1_free(void *ptr) MEMFreeToExpHeap(mem1_heap, ptr); } -void * MEMBucket_alloc(unsigned int size, unsigned int align) +void * MEMBucket_alloc(u32 size, u32 align) { if (align < 4) align = 4; diff --git a/src/system/memory.h b/src/system/memory.h index 59764d0..db67a05 100644 --- a/src/system/memory.h +++ b/src/system/memory.h @@ -26,13 +26,13 @@ extern "C" { void memoryInitialize(void); void memoryRelease(void); -void * MEM2_alloc(unsigned int size, unsigned int align); +void * MEM2_alloc(u32 size, u32 align); void MEM2_free(void *ptr); -void * MEM1_alloc(unsigned int size, unsigned int align); +void * MEM1_alloc(u32 size, u32 align); void MEM1_free(void *ptr); -void * MEMBucket_alloc(unsigned int size, unsigned int align); +void * MEMBucket_alloc(u32 size, u32 align); void MEMBucket_free(void *ptr); #ifdef __cplusplus diff --git a/src/utils/logger.c b/src/utils/logger.c new file mode 100644 index 0000000..7822461 --- /dev/null +++ b/src/utils/logger.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include "dynamic_libs/os_functions.h" +#include "dynamic_libs/socket_functions.h" +#include "logger.h" + +#ifdef DEBUG_LOGGER +static int log_socket = -1; +static struct sockaddr_in connect_addr; +static volatile int log_lock = 0; + + +void log_init() +{ + int broadcastEnable = 1; + log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (log_socket < 0) + return; + + setsockopt(log_socket, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable)); + + memset(&connect_addr, 0, sizeof(struct sockaddr_in)); + connect_addr.sin_family = AF_INET; + connect_addr.sin_port = 4405; + connect_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); +} + +void log_print(const char *str) +{ + // socket is always 0 initially as it is in the BSS + if(log_socket < 0) { + return; + } + + while(log_lock) + os_usleep(1000); + log_lock = 1; + + int len = strlen(str); + int ret; + while (len > 0) { + int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet + ret = sendto(log_socket, str, block, 0, (struct sockaddr *)&connect_addr, sizeof(struct sockaddr_in)); + if(ret < 0) + break; + + len -= ret; + str += ret; + } + + log_lock = 0; +} + +void log_printf(const char *format, ...) +{ + if(log_socket < 0) { + return; + } + + char * tmp = NULL; + + va_list va; + va_start(va, format); + if((vasprintf(&tmp, format, va) >= 0) && tmp) + { + log_print(tmp); + } + va_end(va); + + if(tmp) + free(tmp); +} +#endif diff --git a/src/utils/logger.h b/src/utils/logger.h new file mode 100644 index 0000000..1e8dec1 --- /dev/null +++ b/src/utils/logger.h @@ -0,0 +1,32 @@ +#ifndef __LOGGER_H_ +#define __LOGGER_H_ + +#ifdef __cplusplus +extern "C" { +#endif +#include +#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) + +#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \ + log_printf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ + } while (0) + +#define DEBUG_LOGGER 1 + +#ifdef DEBUG_LOGGER +void log_init(); +#define log_deinit() // depreciated +void log_print(const char *str); +void log_printf(const char *format, ...); +#else +#define log_init() +#define log_deinit() +#define log_print(x) +#define log_printf(x, ...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif