diff --git a/.gitignore b/.gitignore index 808d449..da5a916 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ *.bin *.cscope_file_list *.layout +cmake-build-debug/ +.idea/ +CMakeLists.txt diff --git a/Makefile b/Makefile index fecd272..4be67dc 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ CFLAGS := -std=gnu11 -mcpu=750 -meabi -mhard-float -ffast-math \ CXXFLAGS := -std=gnu++11 -mcpu=750 -meabi -mhard-float -ffast-math \ -O2 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) ASFLAGS := -mregnames -LDFLAGS := -nostartfiles -Wl,--gc-sections +LDFLAGS := -nostartfiles -Wl,--gc-sections,--allow-multiple-definition #--------------------------------------------------------------------------------- Q := @ @@ -55,7 +55,7 @@ MAKEFLAGS += --no-print-directory #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := +LIBS := -lwut #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing @@ -106,8 +106,7 @@ export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ #--------------------------------------------------------------------------------- export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ - -I$(CURDIR)/$(BUILD) -I$(LIBOGC_INC) \ - -I$(PORTLIBS)/include -I$(PORTLIBS)/include/freetype2 + -I$(CURDIR)/$(BUILD) -I$(PORTLIBS)/include #--------------------------------------------------------------------------------- # build a list of library paths diff --git a/src/ElfUtils.cpp b/src/ElfUtils.cpp index c761dba..4f7afd9 100644 --- a/src/ElfUtils.cpp +++ b/src/ElfUtils.cpp @@ -39,7 +39,7 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des *((uint16_t *)(target)) = static_cast((value + 0x8000) >> 16); break; case R_PPC_DTPMOD32: - DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n"); + DEBUG_FUNCTION_LINE("################IMPLEMENT ME"); //*((int32_t *)(target)) = tlsModuleIndex; break; case R_PPC_DTPREL32: @@ -57,18 +57,18 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des case R_PPC_REL14: { auto distance = static_cast(value) - static_cast(target); if (distance > 0x7FFC || distance < -0x7FFC) { - DEBUG_FUNCTION_LINE("***14-bit relative branch cannot hit target.\n"); + DEBUG_FUNCTION_LINE("***14-bit relative branch cannot hit target."); return false; } if (distance & 3) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.\n", -470040); + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470040); return false; } if ((distance >= 0 && (distance & 0xFFFF8000)) || (distance < 0 && ((distance & 0xFFFF8000) != 0xFFFF8000))) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 17 bits before shift must all be the same.\n", -470040); + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 17 bits before shift must all be the same.", -470040); return false; } @@ -83,8 +83,8 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des auto distance = static_cast(value) - static_cast(target); if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) { if(trampolin_data == NULL) { - DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided\n"); - DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); + DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided"); + DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X", value, target, distance); return false; } else { relocation_trampolin_entry_t * freeSlot = NULL; @@ -102,13 +102,13 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des } } if(freeSlot != NULL) { - DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full\n"); - DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); + DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full"); + DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X", value, target, distance); return false; } if(target - (uint32_t)&(freeSlot->trampolin[0]) > 0x1FFFFFC) { - DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer).\n"); - DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); + DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer)."); + DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X", value, target, distance); return false; } @@ -128,22 +128,22 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des uint32_t symbolValue = (uint32_t)&(freeSlot->trampolin[0]); value = symbolValue + addend; distance = static_cast(value) - static_cast(target); - DEBUG_FUNCTION_LINE("Created tramp\n"); + DEBUG_FUNCTION_LINE("Created tramp"); } } if (distance & 3) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.\n", -470022); + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470022); return false; } if (distance < 0 && (distance & 0xFE000000) != 0xFE000000) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (1).\n", -470040); + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (1).", -470040); return false; } if (distance >= 0 && (distance & 0xFE000000)) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (0).\n", -470040); + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (0).", -470040); return false; } @@ -151,7 +151,7 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des break; } default: - DEBUG_FUNCTION_LINE("***ERROR: Unsupported Relocation_Add Type (%08X):\n", type); + DEBUG_FUNCTION_LINE("***ERROR: Unsupported Relocation_Add Type (%08X):", type); return false; } return true; diff --git a/src/dynamic.c b/src/dynamic.c index f125518..6cbf618 100644 --- a/src/dynamic.c +++ b/src/dynamic.c @@ -17,10 +17,9 @@ #define EXPORT_VAR(type, var) type var __attribute__((section(".data"))); -EXPORT_VAR(uint32_t *, pMEMAllocFromDefaultHeapEx); -EXPORT_VAR(uint32_t *, pMEMAllocFromDefaultHeap); -EXPORT_VAR(uint32_t *, pMEMFreeToDefaultHeap); - +EXPORT_VAR(uint32_t *, MEMAllocFromDefaultHeap); +EXPORT_VAR(uint32_t *, MEMAllocFromDefaultHeapEx); +EXPORT_VAR(uint32_t *, MEMFreeToDefaultHeap); void InitFunctionPointers(void) { OSDynLoad_Module handle; @@ -28,10 +27,17 @@ void InitFunctionPointers(void) { addr_OSDynLoad_FindExport = (void*) 0x0102B828; OSDynLoad_Acquire("coreinit.rpl", &handle); - OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeapEx", (void**) &pMEMAllocFromDefaultHeapEx); - OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeap", (void**) &pMEMAllocFromDefaultHeap); - OSDynLoad_FindExport(handle, 1, "MEMFreeToDefaultHeap", (void**) &pMEMFreeToDefaultHeap); + + uint32_t** value = 0; + OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeap", (void**) &value); + MEMAllocFromDefaultHeap = *value; + OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeapEx", (void**) &value); + MEMAllocFromDefaultHeapEx = *value; + OSDynLoad_FindExport(handle, 1, "MEMFreeToDefaultHeap", (void**) &value); + MEMFreeToDefaultHeap = *value; #include "imports.h" + // override failed __rplwrap_exit find export + OSDynLoad_FindExport(handle, 0, "exit", (void**) &addr___rplwrap_exit); } diff --git a/src/elfio/elfio_section.hpp b/src/elfio/elfio_section.hpp index 60e19df..d4f99a0 100644 --- a/src/elfio/elfio_section.hpp +++ b/src/elfio/elfio_section.hpp @@ -283,7 +283,7 @@ class section_impl : public section ret = inflate(&s, Z_FINISH); if (ret != Z_OK && ret != Z_STREAM_END){ - DEBUG_FUNCTION_LINE("NOOOO\n"); + DEBUG_FUNCTION_LINE("NOOOO"); } inflateEnd(&s); @@ -301,7 +301,7 @@ class section_impl : public section } }else{ set_size(0); - DEBUG_FUNCTION_LINE("Failed to allocate memory.\n"); + DEBUG_FUNCTION_LINE("Failed to allocate memory."); } } } diff --git a/src/imports.h b/src/imports.h index 6c113a0..6bd078c 100644 --- a/src/imports.h +++ b/src/imports.h @@ -104,6 +104,10 @@ IMPORT(FSRename); IMPORT(FSGetMountSource); IMPORT(FSMount); IMPORT(FSUnmount); +IMPORT(FSChangeMode); +IMPORT(FSGetPosFile); +IMPORT(OSTicksToCalendarTime); +IMPORT(__rplwrap_exit); IMPORT(IOS_Open); IMPORT(IOS_Close); diff --git a/src/main.cpp b/src/main.cpp index 8ce4274..1bb12a1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,13 +11,14 @@ #include "module/ModuleDataFactory.h" #include "common/module_defines.h" +#include +#include + #include "main.h" #include "kernel.h" #include "dynamic.h" #include "utils/logger.h" #include "utils/utils.h" -#include "utils/sd_fat_devoptab.h" - bool doRelocation(std::vector &relocData, relocation_trampolin_entry_t * tramp_data, uint32_t tramp_length); @@ -41,66 +42,66 @@ bool CheckRunning() { return true; } +extern "C" void __init_wut(); +extern "C" void __fini_wut(); + extern "C" int _start(int argc, char **argv) { doKernelSetup(); InitFunctionPointers(); doKernelSetup2(); - socket_lib_init(); - log_init(); + __init_wut(); + + WHBLogUdpInit(); int res = 0; - if((res = mount_sd_fat("sd")) >= 0) { - DEBUG_FUNCTION_LINE("Mounted sd card\n"); - uint32_t ApplicationMemoryEnd; + uint32_t ApplicationMemoryEnd; - asm volatile("lis %0, __CODE_END@h; ori %0, %0, __CODE_END@l" : "=r" (ApplicationMemoryEnd)); + asm volatile("lis %0, __CODE_END@h; ori %0, %0, __CODE_END@l" : "=r" (ApplicationMemoryEnd)); - ApplicationMemoryEnd = (ApplicationMemoryEnd + 0x100) & 0xFFFFFF00; + ApplicationMemoryEnd = (ApplicationMemoryEnd + 0x100) & 0xFFFFFF00; - module_information_t * gModuleData = (module_information_t *) ApplicationMemoryEnd; + module_information_t * gModuleData = (module_information_t *) ApplicationMemoryEnd; - uint32_t moduleDataStartAddress = ((uint32_t) gModuleData + sizeof(module_information_t)); - moduleDataStartAddress = (moduleDataStartAddress + 0x10000) & 0xFFFF0000; + uint32_t moduleDataStartAddress = ((uint32_t) gModuleData + sizeof(module_information_t)); + moduleDataStartAddress = (moduleDataStartAddress + 0x10000) & 0xFFFF0000; - ModuleData * moduleData = ModuleDataFactory::load("sd:/wiiu/payload.rpx", 0x00FFF000, 0x00FFF000 - ApplicationMemoryEnd, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH); - if(moduleData != NULL) { - DEBUG_FUNCTION_LINE("Loaded module data\n"); - std::vector relocData = moduleData->getRelocationDataList(); - if(!doRelocation(relocData, gModuleData->trampolines,DYN_LINK_TRAMPOLIN_LIST_LENGTH)) { - DEBUG_FUNCTION_LINE("relocations failed\n"); - } - if(moduleData->getBSSAddr() != 0) { - DEBUG_FUNCTION_LINE("memset .bss %08X (%d)\n", moduleData->getBSSAddr(), moduleData->getBSSSize()); - memset((void*)moduleData->getBSSAddr(), 0, moduleData->getBSSSize()); - } - if(moduleData->getSBSSAddr() != 0) { - DEBUG_FUNCTION_LINE("memset .sbss %08X (%d)\n", moduleData->getSBSSAddr(), moduleData->getSBSSSize()); - memset((void*)moduleData->getSBSSAddr(), 0, moduleData->getSBSSSize()); - } - DCFlushRange((void*)0x00800000, 0x00800000); - ICInvalidateRange((void*)0x00800000, 0x00800000); - DEBUG_FUNCTION_LINE("New entrypoint: %08X\n", moduleData->getEntrypoint()); - ((int (*)(int, char **))moduleData->getEntrypoint())(argc, argv); - delete moduleData; - } else { - DEBUG_FUNCTION_LINE("Failed to load module\n"); + ModuleData * moduleData = ModuleDataFactory::load("fs:/vol/external01/wiiu/payload.rpx", 0x00FFF000, 0x00FFF000 - ApplicationMemoryEnd, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH); + if(moduleData != NULL) { + DEBUG_FUNCTION_LINE("Loaded module data"); + std::vector relocData = moduleData->getRelocationDataList(); + if(!doRelocation(relocData, gModuleData->trampolines,DYN_LINK_TRAMPOLIN_LIST_LENGTH)) { + DEBUG_FUNCTION_LINE("relocations failed"); } + if(moduleData->getBSSAddr() != 0) { + DEBUG_FUNCTION_LINE("memset .bss %08X (%d)", moduleData->getBSSAddr(), moduleData->getBSSSize()); + memset((void*)moduleData->getBSSAddr(), 0, moduleData->getBSSSize()); + } + if(moduleData->getSBSSAddr() != 0) { + DEBUG_FUNCTION_LINE("memset .sbss %08X (%d)", moduleData->getSBSSAddr(), moduleData->getSBSSSize()); + memset((void*)moduleData->getSBSSAddr(), 0, moduleData->getSBSSSize()); + } + DCFlushRange((void*)0x00800000, 0x00800000); + ICInvalidateRange((void*)0x00800000, 0x00800000); + DEBUG_FUNCTION_LINE("New entrypoint: %08X", moduleData->getEntrypoint()); + ((int (*)(int, char **))moduleData->getEntrypoint())(argc, argv); + delete moduleData; } else { - DEBUG_FUNCTION_LINE("Mounted sd card failed %d.\n", res); + DEBUG_FUNCTION_LINE("Failed to load module"); } SYSLaunchMenu(); ProcUIInit(OSSavesDone_ReadyToRelease); - DEBUG_FUNCTION_LINE("In ProcUI loop\n"); + DEBUG_FUNCTION_LINE("In ProcUI loop"); while(CheckRunning()) { // wait. OSSleepTicks(OSMillisecondsToTicks(100)); } ProcUIShutdown(); + __fini_wut(); return 0; } @@ -119,7 +120,7 @@ bool doRelocation(std::vector &relocData, relocation_trampolin return false; } if(!ElfUtils::elfLinkOne(cur->getType(), cur->getOffset(), cur->getAddend(), (uint32_t) cur->getDestination(), functionAddress, tramp_data, tramp_length, RELOC_TYPE_IMPORT)) { - DEBUG_FUNCTION_LINE("Relocation failed\n"); + DEBUG_FUNCTION_LINE("Relocation failed"); return false; } } diff --git a/src/module/DynamicLinkingHelper.cpp b/src/module/DynamicLinkingHelper.cpp index eef4960..efad61f 100644 --- a/src/module/DynamicLinkingHelper.cpp +++ b/src/module/DynamicLinkingHelper.cpp @@ -18,7 +18,7 @@ dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_l dyn_linking_function_t * curEntry = &(data->functions[i]); if(strlen(curEntry->functionName) == 0) { if(strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) { - DEBUG_FUNCTION_LINE("Failed to add function name, it's too long.\n"); + DEBUG_FUNCTION_LINE("Failed to add function name, it's too long."); return NULL; } strncpy(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH); @@ -50,7 +50,7 @@ dyn_linking_import_t * DynamicLinkingHelper::getOrAddImport(dyn_linking_relocati dyn_linking_import_t * curEntry = &(data->imports[i]); if(strlen(curEntry->importName) == 0) { if(strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) { - DEBUG_FUNCTION_LINE("Failed to add Import, it's too long.\n"); + DEBUG_FUNCTION_LINE("Failed to add Import, it's too long."); return NULL; } strncpy(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH); @@ -72,13 +72,13 @@ bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t * lin bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, std::string name, ImportRPLInformation * rplInfo) { dyn_linking_import_t * importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo->getName().c_str(),rplInfo->isData()); if(importInfoGbl == NULL) { - DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.\n",DYN_LINK_IMPORT_LIST_LENGTH); + DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.",DYN_LINK_IMPORT_LIST_LENGTH); return false; } dyn_linking_function_t * functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(linking_data, name.c_str()); if(functionInfo == NULL) { - DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d function to be relocated reached.\n",DYN_LINK_FUNCTION_LIST_LENGTH); + DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d function to be relocated reached.",DYN_LINK_FUNCTION_LIST_LENGTH); return false; } diff --git a/src/module/ImportRPLInformation.h b/src/module/ImportRPLInformation.h index ded0760..ee9a05f 100644 --- a/src/module/ImportRPLInformation.h +++ b/src/module/ImportRPLInformation.h @@ -47,7 +47,7 @@ public: rplName = rawSectionName.substr(dimport.size()); data = true; } else { - DEBUG_FUNCTION_LINE("invalid section name\n"); + DEBUG_FUNCTION_LINE("invalid section name"); return NULL; } return new ImportRPLInformation(rplName, data); diff --git a/src/module/ModuleDataFactory.cpp b/src/module/ModuleDataFactory.cpp index 0e728dc..ee54716 100644 --- a/src/module/ModuleDataFactory.cpp +++ b/src/module/ModuleDataFactory.cpp @@ -35,7 +35,7 @@ ModuleData * ModuleDataFactory::load(std::string path, uint32_t destination_addr // Load ELF data if (!reader.load(path)) { - DEBUG_FUNCTION_LINE("Can't find or process ELF file\n"); + DEBUG_FUNCTION_LINE("Can't find or process ELF file"); delete moduleData; return NULL; } @@ -96,7 +96,7 @@ ModuleData * ModuleDataFactory::load(std::string path, uint32_t destination_addr destination -= 0xC0000000; destinations[psec->get_index()] -= 0xC0000000; } else { - DEBUG_FUNCTION_LINE("Unhandled case\n"); + DEBUG_FUNCTION_LINE("Unhandled case"); free(destinations); delete moduleData; return NULL; @@ -105,20 +105,20 @@ ModuleData * ModuleDataFactory::load(std::string path, uint32_t destination_addr const char* p = reader.sections[i]->get_data(); if(psec->get_type() == SHT_NOBITS) { - DEBUG_FUNCTION_LINE("memset section %s %08X [%08X] to 0 (%d bytes)\n", psec->get_name().c_str(), destination, destination + sectionSize, sectionSize); + DEBUG_FUNCTION_LINE("memset section %s %08X [%08X] to 0 (%d bytes)", psec->get_name().c_str(), destination, destination + sectionSize, sectionSize); memset((void*) destination, 0, sectionSize); } else if(psec->get_type() == SHT_PROGBITS) { - DEBUG_FUNCTION_LINE("Copy section %s %08X -> %08X [%08X] (%d bytes)\n", psec->get_name().c_str(), p, destination, destination + sectionSize, sectionSize); + DEBUG_FUNCTION_LINE("Copy section %s %08X -> %08X [%08X] (%d bytes)", psec->get_name().c_str(), p, destination, destination + sectionSize, sectionSize); memcpy((void*) destination, p, sectionSize); } //nextAddress = ROUNDUP(destination + sectionSize,0x100); if(psec->get_name().compare(".bss") == 0) { moduleData->setBSSLocation(destination, sectionSize); - DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X\n", psec->get_name().c_str(), destination, sectionSize); + DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), destination, sectionSize); } else if(psec->get_name().compare(".sbss") == 0) { moduleData->setSBSSLocation(destination, sectionSize); - DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X\n", psec->get_name().c_str(), destination, sectionSize); + DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), destination, sectionSize); } totalSize += sectionSize; @@ -130,9 +130,9 @@ ModuleData * ModuleDataFactory::load(std::string path, uint32_t destination_addr for(uint32_t i = 0; i < sec_num; ++i ) { section* psec = reader.sections[i]; if ((psec->get_type() == SHT_PROGBITS || psec->get_type() == SHT_NOBITS) && (psec->get_flags() & SHF_ALLOC)) { - DEBUG_FUNCTION_LINE("Linking (%d)... %s\n",i,psec->get_name().c_str()); + DEBUG_FUNCTION_LINE("Linking (%d)... %s",i,psec->get_name().c_str()); if (!linkSection(reader, psec->get_index(), (uint32_t) destinations[psec->get_index()], offset_text, offset_data, trampolin_data, trampolin_data_length)) { - DEBUG_FUNCTION_LINE("elfLink failed\n"); + DEBUG_FUNCTION_LINE("elfLink failed"); free(destinations); delete moduleData; return NULL; @@ -151,7 +151,7 @@ ModuleData * ModuleDataFactory::load(std::string path, uint32_t destination_addr free(destinations); moduleData->setEntrypoint(entrypoint); - DEBUG_FUNCTION_LINE("Saved entrypoint as %08X\n", entrypoint); + DEBUG_FUNCTION_LINE("Saved entrypoint as %08X", entrypoint); return moduleData; } @@ -173,7 +173,7 @@ std::vector ModuleDataFactory::getImportRelocationData(elfio& r for (uint32_t i = 0; i < sec_num; ++i ) { section* psec = reader.sections[i]; if(psec->get_type() == SHT_RELA || psec->get_type() == SHT_REL) { - DEBUG_FUNCTION_LINE("Found relocation section %s\n",psec->get_name().c_str()); + DEBUG_FUNCTION_LINE("Found relocation section %s",psec->get_name().c_str()); relocation_section_accessor rel(reader, psec); for ( uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j ) { Elf64_Addr offset; @@ -184,7 +184,7 @@ std::vector ModuleDataFactory::getImportRelocationData(elfio& r Elf_Half sym_section_index; if(!rel.get_entry(j, offset, sym_value, sym_name, type, addend, sym_section_index)) { - DEBUG_FUNCTION_LINE("Failed to get relocation\n"); + DEBUG_FUNCTION_LINE("Failed to get relocation"); break; } @@ -194,7 +194,7 @@ std::vector ModuleDataFactory::getImportRelocationData(elfio& r } ImportRPLInformation * rplInfo = ImportRPLInformation::createImportRPLInformation(infoMap[sym_section_index]); if(rplInfo == NULL) { - DEBUG_FUNCTION_LINE("Failed to create import information\n"); + DEBUG_FUNCTION_LINE("Failed to create import information"); break; } @@ -215,7 +215,7 @@ bool ModuleDataFactory::linkSection(elfio& reader, uint32_t section_index, uint3 for (uint32_t i = 0; i < sec_num; ++i ) { section* psec = reader.sections[i]; if(psec->get_info() == section_index) { - DEBUG_FUNCTION_LINE("Found relocation section %s\n",psec->get_name().c_str()); + DEBUG_FUNCTION_LINE("Found relocation section %s",psec->get_name().c_str()); relocation_section_accessor rel(reader, psec); for ( uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j ) { Elf64_Addr offset; @@ -226,7 +226,7 @@ bool ModuleDataFactory::linkSection(elfio& reader, uint32_t section_index, uint3 Elf_Half sym_section_index; if(!rel.get_entry(j, offset, sym_value, sym_name, type, addend, sym_section_index)) { - DEBUG_FUNCTION_LINE("Failed to get relocation\n"); + DEBUG_FUNCTION_LINE("Failed to get relocation"); break; } @@ -243,23 +243,23 @@ bool ModuleDataFactory::linkSection(elfio& reader, uint32_t section_index, uint3 } else if(adjusted_sym_value == 0x0) { // } else { - DEBUG_FUNCTION_LINE("Unhandled case %08X\n",adjusted_sym_value); + DEBUG_FUNCTION_LINE("Unhandled case %08X",adjusted_sym_value); return false; } if(sym_section_index == SHN_ABS) { // } else if(sym_section_index > SHN_LORESERVE) { - DEBUG_FUNCTION_LINE("NOT IMPLEMENTED: %04X\n", sym_section_index); + DEBUG_FUNCTION_LINE("NOT IMPLEMENTED: %04X", sym_section_index); return false; } if(!ElfUtils::elfLinkOne(type, offset, addend, destination, adjusted_sym_value, trampolin_data, trampolin_data_length, RELOC_TYPE_FIXED)) { - DEBUG_FUNCTION_LINE("Link failed\n"); + DEBUG_FUNCTION_LINE("Link failed"); return false; } } - DEBUG_FUNCTION_LINE("done\n"); + DEBUG_FUNCTION_LINE("done"); } } return true; diff --git a/src/module/RelocationData.cpp b/src/module/RelocationData.cpp index 8fdcc3a..fb2197b 100644 --- a/src/module/RelocationData.cpp +++ b/src/module/RelocationData.cpp @@ -2,5 +2,5 @@ #include "utils/StringTools.h" std::string RelocationData::toString(){ - return StringTools::strfmt("%s destination: %08X offset: %08X type: %02X addend: %d rplName: %s isData: %d \n",name.c_str(), destination, offset, type, addend, rplInfo->getName().c_str(), rplInfo->isData() ); + return StringTools::strfmt("%s destination: %08X offset: %08X type: %02X addend: %d rplName: %s isData: %d" ,name.c_str(), destination, offset, type, addend, rplInfo->getName().c_str(), rplInfo->isData() ); } diff --git a/src/utils/FSOSUtils.cpp b/src/utils/FSOSUtils.cpp deleted file mode 100644 index c5fe3bf..0000000 --- a/src/utils/FSOSUtils.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "utils/logger.h" -#include "FSOSUtils.h" - -#define FS_MOUNT_SOURCE_SIZE 0x300 -#define FS_MAX_MOUNTPATH_SIZE 128 -#define FS_SOURCETYPE_EXTERNAL 0 - -int32_t FSOSUtils::MountFS(FSClient *pClient, FSCmdBlock *pCmd, char **mount_path) { - int32_t result = -1; - DEBUG_FUNCTION_LINE("\n"); - FSMountSource *mountSrc = (FSMountSource*) malloc(sizeof(FSMountSource)); - if(!mountSrc) { - return -3; - } - - DEBUG_FUNCTION_LINE("\n"); - char* mountPath = (char*) malloc(FS_MAX_MOUNTPATH_SIZE); - if(!mountPath) { - free(mountSrc); - mountSrc = NULL; - return -4; - } - DEBUG_FUNCTION_LINE("\n"); - memset(mountSrc, 0, FS_MOUNT_SOURCE_SIZE); - memset(mountPath, 0, FS_MAX_MOUNTPATH_SIZE); - - - // Mount sdcard - if (FSGetMountSource(pClient, pCmd, FS_MOUNT_SOURCE_SD, mountSrc, -1) == 0) { - DEBUG_FUNCTION_LINE("\n"); - result = FSMount(pClient, pCmd, mountSrc, mountPath, FS_MAX_MOUNTPATH_SIZE, -1); - if((result == 0) && mount_path) { - *mount_path = (char*)malloc(strlen(mountPath) + 1); - if(*mount_path) - strcpy(*mount_path, mountPath); - } - } - - DEBUG_FUNCTION_LINE("\n"); - free(mountPath); - free(mountSrc); - - mountPath = NULL; - mountSrc = NULL; - - return result; -} - -int32_t FSOSUtils::UmountFS(FSClient *pClient, FSCmdBlock *pCmd, const char *mountPath) { - int32_t result = -1; - result = FSUnmount(pClient, pCmd, mountPath, -1); - - return result; -} diff --git a/src/utils/FSOSUtils.h b/src/utils/FSOSUtils.h deleted file mode 100644 index 648af2e..0000000 --- a/src/utils/FSOSUtils.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __FS_OS_UTILS_H_ -#define __FS_OS_UTILS_H_ - -#include -#include - -class FSOSUtils { -public: - static int32_t MountFS(FSClient *pClient, FSCmdBlock *pCmd, char **mount_path); - static int32_t UmountFS(FSClient *pClient, FSCmdBlock *pCmd, const char *mountPath); -}; - -#endif // __FS_OS_UTILS_H_ diff --git a/src/utils/logger.h b/src/utils/logger.h index d026b05..05fe012 100644 --- a/src/utils/logger.h +++ b/src/utils/logger.h @@ -1,11 +1,11 @@ -#ifndef __LOGGER_H_ -#define __LOGGER_H_ +#pragma once #ifdef __cplusplus extern "C" { #endif #include +#include void log_init_(); //void log_deinit_(void); @@ -28,11 +28,9 @@ void OSFatal_printf(const char *format, ...); #define log_printf(FMT, ARGS...) log_printf_(FMT, ## ARGS); #define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \ - log_printf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ + WHBLogPrintf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ } while (0) #ifdef __cplusplus } #endif - -#endif diff --git a/src/utils/memory.c b/src/utils/memory.c deleted file mode 100644 index 214726d..0000000 --- a/src/utils/memory.c +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 Dimok - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - ****************************************************************************/ -#include -#include -#include -#include -#include -#include - -extern uint32_t * pMEMAllocFromDefaultHeapEx; -extern uint32_t * pMEMAllocFromDefaultHeap; -extern uint32_t * pMEMFreeToDefaultHeap; - -//!------------------------------------------------------------------------------------------- -//! reent versions -//!------------------------------------------------------------------------------------------- -void *_malloc_r(struct _reent *r, size_t size) { - void *ptr = ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(size); - if (!ptr) { - r->_errno = ENOMEM; - } - return ptr; -} - -void *_calloc_r(struct _reent *r, size_t num, size_t size) { - void *ptr = ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(size); - if (ptr) { - memset(ptr, 0, num * size); - } else { - r->_errno = ENOMEM; - } - - return ptr; -} - -void *_memalign_r(struct _reent *r, size_t align, size_t size) { - return ((void * (*)(size_t, size_t))(*pMEMAllocFromDefaultHeapEx))(size, align); -} - -void _free_r(struct _reent *r, void *ptr) { - if (ptr) { - ((void (*)(void *))(*pMEMFreeToDefaultHeap))(ptr); - } -} - -void *_realloc_r(struct _reent *r, void *p, size_t size) { - void *new_ptr = ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(size); - if (!new_ptr) { - r->_errno = ENOMEM; - return new_ptr; - } - - if (p) { - size_t old_size = MEMGetSizeForMBlockExpHeap(p); - memcpy(new_ptr, p, old_size <= size ? old_size : size); - ((void (*)(void *))(*pMEMFreeToDefaultHeap))(p); - } - return new_ptr; -} - -struct mallinfo _mallinfo_r(struct _reent *r) { - struct mallinfo info = { 0 }; - return info; -} - -void -_malloc_stats_r(struct _reent *r) { -} - -int -_mallopt_r(struct _reent *r, int param, int value) { - return 0; -} - -size_t -_malloc_usable_size_r(struct _reent *r, void *ptr) { - return MEMGetSizeForMBlockExpHeap(ptr); -} - -void * -_valloc_r(struct _reent *r, size_t size) { - return ((void * (*)(size_t, size_t))(*pMEMAllocFromDefaultHeapEx))(size, OS_PAGE_SIZE); -} - -void * -_pvalloc_r(struct _reent *r, size_t size) { - return ((void * (*)(size_t, size_t))(*pMEMAllocFromDefaultHeapEx))((size + (OS_PAGE_SIZE - 1)) & ~(OS_PAGE_SIZE - 1), OS_PAGE_SIZE); -} - -int -_malloc_trim_r(struct _reent *r, size_t pad) { - return 0; -} diff --git a/src/utils/memory.h b/src/utils/memory.h deleted file mode 100644 index db67a05..0000000 --- a/src/utils/memory.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 Dimok - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - ****************************************************************************/ -#ifndef __MEMORY_H_ -#define __MEMORY_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -void memoryInitialize(void); -void memoryRelease(void); - -void * MEM2_alloc(u32 size, u32 align); -void MEM2_free(void *ptr); - -void * MEM1_alloc(u32 size, u32 align); -void MEM1_free(void *ptr); - -void * MEMBucket_alloc(u32 size, u32 align); -void MEMBucket_free(void *ptr); - -#ifdef __cplusplus -} -#endif - -#endif // __MEMORY_H_ diff --git a/src/utils/sd_fat_devoptab.cpp b/src/utils/sd_fat_devoptab.cpp deleted file mode 100644 index 527b7fa..0000000 --- a/src/utils/sd_fat_devoptab.cpp +++ /dev/null @@ -1,1016 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sd_fat_devoptab.h" -#include "FSOSUtils.h" -#include "utils/StringTools.h" -#include "utils/logger.h" - -#define FS_ALIGNMENT 0x40 -#define FS_ALIGN(x) (((x) + FS_ALIGNMENT - 1) & ~(FS_ALIGNMENT - 1)) - -typedef struct _sd_fat_private_t { - char *mount_path; - FSClient *pClient; - FSCmdBlock *pCmd; - OSMutex *pMutex; -} sd_fat_private_t; - -typedef struct _sd_fat_file_state_t { - sd_fat_private_t *dev; - int fd; /* File descriptor */ - int flags; /* Opening flags */ - bool read; /* True if allowed to read from file */ - bool write; /* True if allowed to write to file */ - bool append; /* True if allowed to append to file */ - uint64_t pos; /* Current position within the file (in bytes) */ - uint64_t len; /* Total length of the file (in bytes) */ - struct _sd_fat_file_state_t *prevOpenFile; /* The previous entry in a double-linked FILO list of open files */ - struct _sd_fat_file_state_t *nextOpenFile; /* The next entry in a double-linked FILO list of open files */ -} sd_fat_file_state_t; - -typedef struct _sd_fat_dir_entry_t { - sd_fat_private_t *dev; - int dirHandle; -} sd_fat_dir_entry_t; - -static sd_fat_private_t *sd_fat_get_device_data(const char *path) { - const devoptab_t *devoptab = NULL; - char name[128] = {0}; - int i; - - // Get the device name from the path - strncpy(name, path, 127); - strtok(name, ":/"); - - // Search the devoptab table for the specified device name - // NOTE: We do this manually due to a 'bug' in GetDeviceOpTab - // which ignores names with suffixes and causes names - // like "ntfs" and "ntfs1" to be seen as equals - for (i = 3; i < STD_MAX; i++) { - devoptab = devoptab_list[i]; - if (devoptab && devoptab->name) { - if (strcmp(name, devoptab->name) == 0) { - return (sd_fat_private_t *)devoptab->deviceData; - } - } - } - - return NULL; -} - -static char *sd_fat_real_path (const char *path, sd_fat_private_t *dev) { - // Sanity check - if (!path) - return NULL; - - // Move the path pointer to the start of the actual path - if (strchr(path, ':') != NULL) { - path = strchr(path, ':') + 1; - } - - int mount_len = strlen(dev->mount_path); - - char *new_name = (char*)malloc(mount_len + strlen(path) + 1); - if(new_name) { - strcpy(new_name, dev->mount_path); - strcpy(new_name + mount_len, path); - return new_name; - } - return new_name; -} - -static int sd_fat_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fileStruct; - - file->dev = dev; - // Determine which mode the file is opened for - file->flags = flags; - - const char *mode_str; - - if ((flags & 0x03) == O_RDONLY) { - file->read = true; - file->write = false; - file->append = false; - mode_str = "r"; - } else if ((flags & 0x03) == O_WRONLY) { - file->read = false; - file->write = true; - file->append = (flags & O_APPEND); - mode_str = file->append ? "a" : "w"; - } else if ((flags & 0x03) == O_RDWR) { - file->read = true; - file->write = true; - file->append = (flags & O_APPEND); - mode_str = file->append ? "a+" : "r+"; - } else { - r->_errno = EACCES; - return -1; - } - - int32_t fd = -1; - - OSLockMutex((OSMutex *)dev->pMutex); - - char *real_path = sd_fat_real_path(path, dev); - if(!path) { - r->_errno = ENOMEM; - OSUnlockMutex((OSMutex *)dev->pMutex); - return -1; - } - - int result = FSOpenFile(dev->pClient, dev->pCmd, real_path, mode_str, (FSFileHandle*) &fd, -1); - - free(real_path); - - if(result == 0) { - FSStat stats; - result = FSGetStatFile(dev->pClient, dev->pCmd, fd, &stats, -1); - if(result != 0) { - FSCloseFile(dev->pClient, dev->pCmd, fd, -1); - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; - } - file->fd = fd; - file->pos = 0; - file->len = stats.size; - OSUnlockMutex(dev->pMutex); - return (int)file; - } - - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; -} - - -static int sd_fat_close_r (struct _reent *r, void *fd) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - int result = FSCloseFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); - - OSUnlockMutex(file->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - return 0; -} - -static off_t sd_fat_seek_r (struct _reent *r, void* fd, off_t pos, int dir) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - switch(dir) { - case SEEK_SET: - file->pos = pos; - break; - case SEEK_CUR: - file->pos += pos; - break; - case SEEK_END: - file->pos = file->len + pos; - break; - default: - r->_errno = EINVAL; - return -1; - } - - int result = FSSetPosFile(file->dev->pClient, file->dev->pCmd, file->fd, file->pos, -1); - - OSUnlockMutex(file->dev->pMutex); - - if(result == 0) { - return file->pos; - } - - return result; -} - -static ssize_t sd_fat_write_r (struct _reent *r, void *fd, const char *ptr, size_t len) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return 0; - } - - if(!file->write) { - r->_errno = EACCES; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - size_t len_aligned = FS_ALIGN(len); - if(len_aligned > 0x4000) - len_aligned = 0x4000; - - unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned); - if(!tmpBuf) { - r->_errno = ENOMEM; - OSUnlockMutex(file->dev->pMutex); - return 0; - } - - size_t done = 0; - - while(done < len) { - size_t write_size = (len_aligned < (len - done)) ? len_aligned : (len - done); - memcpy(tmpBuf, ptr + done, write_size); - - int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, write_size, file->fd, 0, -1); - if(result < 0) { - r->_errno = result; - break; - } else if(result == 0) { - if(write_size > 0) - done = 0; - break; - } else { - done += result; - file->pos += result; - } - } - - free(tmpBuf); - OSUnlockMutex(file->dev->pMutex); - return done; -} - -static ssize_t sd_fat_read_r (struct _reent *r, void* fd, char *ptr, size_t len) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return 0; - } - - if(!file->read) { - r->_errno = EACCES; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - size_t len_aligned = FS_ALIGN(len); - if(len_aligned > 0x4000) - len_aligned = 0x4000; - - unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned); - if(!tmpBuf) { - r->_errno = ENOMEM; - OSUnlockMutex(file->dev->pMutex); - return 0; - } - - size_t done = 0; - - while(done < len) { - size_t read_size = (len_aligned < (len - done)) ? len_aligned : (len - done); - - int result = FSReadFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, read_size, file->fd, 0, -1); - if(result < 0) { - r->_errno = result; - done = 0; - break; - } else if(result == 0) { - //! TODO: error on read_size > 0 - break; - } else { - memcpy(ptr + done, tmpBuf, read_size); - done += result; - file->pos += result; - } - } - - free(tmpBuf); - OSUnlockMutex(file->dev->pMutex); - return done; -} - - -static int sd_fat_fstat_r (struct _reent *r, void* fd, struct stat *st) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - // Zero out the stat buffer - memset(st, 0, sizeof(struct stat)); - - FSStat stats; - int result = FSGetStatFile(file->dev->pClient, file->dev->pCmd, file->fd, &stats, -1); - if(result != 0) { - r->_errno = result; - OSUnlockMutex(file->dev->pMutex); - return -1; - } - - st->st_mode = S_IFREG; - st->st_size = stats.size; - st->st_blocks = (stats.size + 511) >> 9; - st->st_nlink = 1; - - // Fill in the generic entry stats - st->st_dev = stats.entryId; - st->st_uid = stats.owner; - st->st_gid = stats.group; - st->st_ino = stats.entryId; - st->st_atime = stats.modified; - st->st_ctime = stats.created; - st->st_mtime = stats.modified; - OSUnlockMutex(file->dev->pMutex); - return 0; -} - -static int sd_fat_ftruncate_r (struct _reent *r, void* fd, off_t len) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - int result = FSTruncateFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); - - OSUnlockMutex(file->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_fsync_r (struct _reent *r, void* fd) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - int result = FSFlushFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); - - OSUnlockMutex(file->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_stat_r (struct _reent *r, const char *path, struct stat *st) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - // Zero out the stat buffer - memset(st, 0, sizeof(struct stat)); - - char *real_path = sd_fat_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - FSStat stats; - - int result = FSGetStat(dev->pClient, dev->pCmd, real_path, &stats, -1); - - free(real_path); - - if(result < 0) { - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; - } - - // mark root also as directory - st->st_mode = ((stats.flags & 0x80000000) || (strlen(dev->mount_path) + 1 == strlen(real_path)))? S_IFDIR : S_IFREG; - st->st_nlink = 1; - st->st_size = stats.size; - st->st_blocks = (stats.size + 511) >> 9; - // Fill in the generic entry stats - st->st_dev = stats.entryId; - st->st_uid = stats.owner; - st->st_gid = stats.group; - st->st_ino = stats.entryId; - st->st_atime = stats.modified; - st->st_ctime = stats.created; - st->st_mtime = stats.modified; - - OSUnlockMutex(dev->pMutex); - - return 0; -} - -static int sd_fat_link_r (struct _reent *r, const char *existing, const char *newLink) { - r->_errno = ENOTSUP; - return -1; -} - -static int sd_fat_unlink_r (struct _reent *r, const char *name) { - sd_fat_private_t *dev = sd_fat_get_device_data(name); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = sd_fat_real_path(name, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - - int result = FSRemove(dev->pClient, dev->pCmd, real_path, -1); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_chdir_r (struct _reent *r, const char *name) { - sd_fat_private_t *dev = sd_fat_get_device_data(name); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = sd_fat_real_path(name, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = FSChangeDir(dev->pClient, dev->pCmd, real_path, -1); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_rename_r (struct _reent *r, const char *oldName, const char *newName) { - sd_fat_private_t *dev = sd_fat_get_device_data(oldName); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_oldpath = sd_fat_real_path(oldName, dev); - if(!real_oldpath) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - char *real_newpath = sd_fat_real_path(newName, dev); - if(!real_newpath) { - r->_errno = ENOMEM; - free(real_oldpath); - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = FSRename(dev->pClient, dev->pCmd, real_oldpath, real_newpath, -1); - - free(real_oldpath); - free(real_newpath); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; - -} - -static int sd_fat_mkdir_r (struct _reent *r, const char *path, int mode) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = sd_fat_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = FSMakeDir(dev->pClient, dev->pCmd, real_path, -1); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - // Zero out the stat buffer - memset(buf, 0, sizeof(struct statvfs)); - - char *real_path = sd_fat_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - uint64_t size; - - int result = FSGetFreeSpaceSize(dev->pClient, dev->pCmd, real_path, &size, -1); - - free(real_path); - - if(result < 0) { - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; - } - - // File system block size - buf->f_bsize = 512; - - // Fundamental file system block size - buf->f_frsize = 512; - - // Total number of blocks on file system in units of f_frsize - buf->f_blocks = size >> 9; // this is unknown - - // Free blocks available for all and for non-privileged processes - buf->f_bfree = buf->f_bavail = size >> 9; - - // Number of inodes at this point in time - buf->f_files = 0xffffffff; - - // Free inodes available for all and for non-privileged processes - buf->f_ffree = 0xffffffff; - - // File system id - buf->f_fsid = (int)dev; - - // Bit mask of f_flag values. - buf->f_flag = 0; - - // Maximum length of filenames - buf->f_namemax = 255; - - OSUnlockMutex(dev->pMutex); - - return 0; -} - -static DIR_ITER *sd_fat_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return NULL; - } - - sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; - - OSLockMutex(dev->pMutex); - - char *real_path = sd_fat_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return NULL; - } - - int32_t dirHandle; - - int result = FSOpenDir(dev->pClient, dev->pCmd, real_path, (FSDirectoryHandle*) &dirHandle, -1); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return NULL; - } - - dirIter->dev = dev; - dirIter->dirHandle = dirHandle; - - return dirState; -} - -static int sd_fat_dirclose_r (struct _reent *r, DIR_ITER *dirState) { - sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; - if(!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - int result = FSCloseDir(dirIter->dev->pClient, dirIter->dev->pCmd, dirIter->dirHandle, -1); - - OSUnlockMutex(dirIter->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - return 0; -} - -static int sd_fat_dirreset_r (struct _reent *r, DIR_ITER *dirState) { - sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; - if(!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - int result = FSRewindDir(dirIter->dev->pClient, dirIter->dev->pCmd, dirIter->dirHandle, -1); - - OSUnlockMutex(dirIter->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - return 0; -} - -static int sd_fat_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st) { - sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; - if(!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - FSDirectoryEntry * dir_entry = (FSDirectoryEntry *)malloc(sizeof(FSDirectoryEntry)); - - int result = FSReadDir(dirIter->dev->pClient, dirIter->dev->pCmd, dirIter->dirHandle, dir_entry, -1); - if(result < 0) { - free(dir_entry); - r->_errno = result; - OSUnlockMutex(dirIter->dev->pMutex); - return -1; - } - - // Fetch the current entry - strcpy(filename, dir_entry->name); - - if(st) { - memset(st, 0, sizeof(struct stat)); - st->st_mode = (dir_entry->info.flags & 0x80000000) ? S_IFDIR : S_IFREG; - st->st_nlink = 1; - st->st_size = dir_entry->info.size; - st->st_blocks = (dir_entry->info.size + 511) >> 9; - st->st_dev = dir_entry->info.entryId; - st->st_uid = dir_entry->info.owner; - st->st_gid = dir_entry->info.group; - st->st_ino = dir_entry->info.entryId; - st->st_atime = dir_entry->info.modified; - st->st_ctime = dir_entry->info.created; - st->st_mtime = dir_entry->info.modified; - } - - free(dir_entry); - OSUnlockMutex(dirIter->dev->pMutex); - return 0; -} - -// SD device driver devoptab -static const devoptab_t devops_sd_fat = { - NULL, /* Device name */ - sizeof (sd_fat_file_state_t), - sd_fat_open_r, - sd_fat_close_r, - sd_fat_write_r, - sd_fat_read_r, - sd_fat_seek_r, - sd_fat_fstat_r, - sd_fat_stat_r, - sd_fat_link_r, - sd_fat_unlink_r, - sd_fat_chdir_r, - sd_fat_rename_r, - sd_fat_mkdir_r, - sizeof (sd_fat_dir_entry_t), - sd_fat_diropen_r, - sd_fat_dirreset_r, - sd_fat_dirnext_r, - sd_fat_dirclose_r, - sd_fat_statvfs_r, - sd_fat_ftruncate_r, - sd_fat_fsync_r, - NULL, /* Device data */ - NULL, /* sd_fat_chmod_r */ - NULL, /* sd_fat_fchmod_r */ - NULL, /* sd_fat_rmdir_r */ - NULL, - NULL -}; - - -static int sd_fat_add_device (const char *name, const char *mount_path, FSClient *pClient, FSCmdBlock *pCmd) { - devoptab_t *dev = NULL; - char *devname = NULL; - char *devpath = NULL; - int i; - - // Sanity check - if (!name) { - errno = EINVAL; - return -1; - } - - // Allocate a devoptab for this device - dev = (devoptab_t *) malloc(sizeof(devoptab_t) + strlen(name) + 1); - if (!dev) { - errno = ENOMEM; - return -1; - } - - // Use the space allocated at the end of the devoptab for storing the device name - devname = (char*)(dev + 1); - strcpy(devname, name); - - // create private data - int mount_path_len = 0; - if(mount_path != NULL) { - mount_path_len = strlen(mount_path); - } - sd_fat_private_t *priv = (sd_fat_private_t *)malloc(sizeof(sd_fat_private_t) + mount_path_len + 1); - if(!priv) { - free(dev); - errno = ENOMEM; - return -1; - } - - devpath = (char*)(priv+1); - if(mount_path != NULL) { - strcpy(devpath, mount_path); - } - - // setup private data - priv->mount_path = devpath; - priv->pClient = pClient; - priv->pCmd = pCmd; - priv->pMutex = (OSMutex*) malloc(sizeof(OSMutex)); - - if(!priv->pMutex) { - free(dev); - free(priv); - errno = ENOMEM; - return -1; - } - - OSInitMutex(priv->pMutex); - - // Setup the devoptab - memcpy(dev, &devops_sd_fat, sizeof(devoptab_t)); - dev->name = devname; - dev->deviceData = priv; - - // Add the device to the devoptab table (if there is a free slot) - for (i = 3; i < STD_MAX; i++) { - if (devoptab_list[i] == devoptab_list[0]) { - devoptab_list[i] = dev; - return 0; - } - } - - // failure, free all memory - free(priv); - free(dev); - - // If we reach here then there are no free slots in the devoptab table for this device - errno = EADDRNOTAVAIL; - return -1; -} - -/* -Because of some weird reason unmounting doesn't work properly. -This fix if mainly when a usb drive is connected. -It resets the devoptab_list, otherwise mounting again would throw an exception (in strlen). -No memory is free'd here. Maybe a problem?!?!? -*/ - -void deleteDevTabsNames() { - const devoptab_t * devoptab = NULL; - uint32_t last_entry = (uint32_t) devoptab_list[STD_MAX-1]; - for (int i = 3; i < STD_MAX; i++) { - devoptab = devoptab_list[i]; - - if (devoptab) { - //log_printf("check devotab %d %08X\n",i,devoptab); - if((uint32_t) devoptab != last_entry) { - devoptab_list[i] = (const devoptab_t *)last_entry; - //log_printf("Removed devotab %d %08X %08X %08X\n",i,devoptab,devoptab->name,devoptab->deviceData); - } - } - } -} - -static int sd_fat_remove_device (const char *path, FSClient **pClient, FSCmdBlock **pCmd, char **mountPath) { - const devoptab_t *devoptab = NULL; - char name[128] = {0}; - int i; - - // Get the device name from the path - strncpy(name, path, 127); - strtok(name, ":/"); - - // Find and remove the specified device from the devoptab table - // NOTE: We do this manually due to a 'bug' in RemoveDevice - // which ignores names with suffixes and causes names - // like "ntfs" and "ntfs1" to be seen as equals - for (i = 3; i < STD_MAX; i++) { - devoptab = devoptab_list[i]; - if (devoptab && devoptab->name) { - if (strcmp(name, devoptab->name) == 0) { - devoptab_list[i] = devoptab_list[0]; - - if(devoptab->deviceData) { - sd_fat_private_t *priv = (sd_fat_private_t *)devoptab->deviceData; - if(pClient != NULL) *pClient = priv->pClient; - if(pCmd != NULL) *pCmd = priv->pCmd; - if(mountPath != NULL) { - *mountPath = (char*) malloc(strlen(priv->mount_path)+1); - if(*mountPath) - strcpy(*mountPath, priv->mount_path); - } - if(priv->pMutex) - free(priv->pMutex); - free(devoptab->deviceData); - } - - free((devoptab_t*)devoptab); - return 0; - } - } - } - - return -1; -} - -int32_t mount_sd_fat(const char *path) { - int result = -1; - - // get command and client - FSClient* pClient = (FSClient *) malloc(sizeof(FSClient)); - FSCmdBlock* pCmd = (FSCmdBlock*) malloc(sizeof(FSCmdBlock)); - - if(!pClient || !pCmd) { - // just in case free if not 0 - if(pClient) - free(pClient); - if(pCmd) - free(pCmd); - return -2; - } - - FSInit(); - FSInitCmdBlock(pCmd); - FSAddClient(pClient, 0); - - char *mountPath = NULL; - - DEBUG_FUNCTION_LINE("Calling MountFS\n"); - if(FSOSUtils::MountFS(pClient, pCmd, &mountPath) == 0) { - result = sd_fat_add_device(path, mountPath, pClient, pCmd); - free(mountPath); - } - - return result; -} - -int32_t unmount_sd_fat(const char *path) { - FSClient *pClient = 0; - FSCmdBlock *pCmd = 0; - char *mountPath = 0; - - int result = sd_fat_remove_device(path, &pClient, &pCmd, &mountPath); - if(result == 0) { - FSOSUtils::UmountFS(pClient, pCmd, mountPath); - FSDelClient(pClient,0); - free(pClient); - free(pCmd); - free(mountPath); - //FSShutdown(); - } - return result; -} - -int32_t mount_fake() { - return sd_fat_add_device("fake", NULL, NULL, NULL); -} - -int32_t unmount_fake() { - return sd_fat_remove_device ("fake", NULL,NULL,NULL); -} diff --git a/src/utils/sd_fat_devoptab.h b/src/utils/sd_fat_devoptab.h deleted file mode 100644 index 88a1c04..0000000 --- a/src/utils/sd_fat_devoptab.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#ifndef __SD_FAT_DEVOPTAB_H_ -#define __SD_FAT_DEVOPTAB_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -int32_t mount_sd_fat(const char *path); -int32_t unmount_sd_fat(const char *path); -int32_t mount_fake(); -int32_t unmount_fake(); -void deleteDevTabsNames(); -#ifdef __cplusplus -} -#endif - -#endif // __SD_FAT_DEVOPTAB_H_