Format the code via clang-format

This commit is contained in:
Maschell 2022-02-04 21:44:03 +01:00
parent 66e5d5b9f3
commit 00dec53199
61 changed files with 528 additions and 427 deletions

67
.clang-format Normal file
View File

@ -0,0 +1,67 @@
# Generated from CLion C/C++ Code Style settings
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: Consecutive
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignOperands: Align
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Always
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
ColumnLimit: 0
CompactNamespaces: false
ContinuationIndentWidth: 8
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PointerAlignment: Right
ReflowComments: false
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Never

View File

@ -6,8 +6,16 @@ on:
- master - master
jobs: jobs:
clang-format:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: clang-format
run: |
docker run --rm -v ${PWD}:/src wiiuenv/clang-format:13.0.0-2 -r ./source ./relocator/src
build-binary: build-binary:
runs-on: ubuntu-18.04 runs-on: ubuntu-18.04
needs: clang-format
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: build binary - name: build binary
@ -26,7 +34,7 @@ jobs:
id: get_repository_name id: get_repository_name
run: | run: |
echo REPOSITORY_NAME=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $2}' | sed -e "s/:refs//") >> $GITHUB_ENV echo REPOSITORY_NAME=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $2}' | sed -e "s/:refs//") >> $GITHUB_ENV
echo DATETIME=$(echo $(date '+%Y%m%d-%H%M%S')) >> $GITHUB_ENV echo DATETIME=$(echo $(date '+%Y%m%d-%H%M%S')) >> $GITHUB_ENV
- uses: actions/download-artifact@master - uses: actions/download-artifact@master
with: with:
name: binary name: binary

View File

@ -3,8 +3,16 @@ name: CI-PR
on: [pull_request] on: [pull_request]
jobs: jobs:
clang-format:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: clang-format
run: |
docker run --rm -v ${PWD}:/src wiiuenv/clang-format:13.0.0-2 -r ./source ./relocator/src
build-binary: build-binary:
runs-on: ubuntu-18.04 runs-on: ubuntu-18.04
needs: clang-format
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: build binary - name: build binary

View File

@ -1,3 +1,5 @@
[![CI-Release](https://github.com/wiiu-env/WUMSLoader/actions/workflows/ci.yml/badge.svg)](https://github.com/wiiu-env/WUMSLoader/actions/workflows/ci.yml)
# Wii U Module System Loader # Wii U Module System Loader
This is a payload that should be run with [EnvironmentLoader](https://github.com/wiiu-env/EnvironmentLoader). This is a payload that should be run with [EnvironmentLoader](https://github.com/wiiu-env/EnvironmentLoader).
@ -29,6 +31,9 @@ docker run -it --rm -v ${PWD}:/project wumsloader-builder make
docker run -it --rm -v ${PWD}:/project wumsloader-builder make clean docker run -it --rm -v ${PWD}:/project wumsloader-builder make clean
``` ```
## Format the code via docker
`docker run --rm -v ${PWD}:/src wiiuenv/clang-format:13.0.0-2 -r ./source ./relocator/src -i`
## Credits ## Credits
- maschell - maschell

View File

@ -9,7 +9,7 @@ dyn_linking_function_t *DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_li
return nullptr; return nullptr;
} }
dyn_linking_function_t *result = nullptr; dyn_linking_function_t *result = nullptr;
for (auto &function: data->functions) { for (auto &function : data->functions) {
dyn_linking_function_t *curEntry = &function; dyn_linking_function_t *curEntry = &function;
if (strlen(curEntry->functionName) == 0) { if (strlen(curEntry->functionName) == 0) {
if (strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) { if (strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) {
@ -41,7 +41,7 @@ dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocatio
return nullptr; return nullptr;
} }
dyn_linking_import_t *result = nullptr; dyn_linking_import_t *result = nullptr;
for (auto &import: data->imports) { for (auto &import : data->imports) {
dyn_linking_import_t *curEntry = &import; dyn_linking_import_t *curEntry = &import;
if (strlen(curEntry->importName) == 0) { if (strlen(curEntry->importName) == 0) {
if (strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) { if (strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) {
@ -50,7 +50,7 @@ dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocatio
} }
strncpy(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH); strncpy(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH);
curEntry->isData = isData; curEntry->isData = isData;
result = curEntry; result = curEntry;
break; break;
} }
if (strncmp(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH) == 0 && (curEntry->isData == isData)) { if (strncmp(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH) == 0 && (curEntry->isData == isData)) {
@ -95,12 +95,12 @@ bool DynamicLinkingHelper::addRelocationEntry(dyn_linking_relocation_entry_t *li
if (curEntry->functionEntry != nullptr) { if (curEntry->functionEntry != nullptr) {
continue; continue;
} }
curEntry->type = type; curEntry->type = type;
curEntry->offset = offset; curEntry->offset = offset;
curEntry->addend = addend; curEntry->addend = addend;
curEntry->destination = destination; curEntry->destination = destination;
curEntry->functionEntry = functionName; curEntry->functionEntry = functionName;
curEntry->importEntry = importInfo; curEntry->importEntry = importInfo;
return true; return true;
} }

View File

@ -1,10 +1,10 @@
#pragma once #pragma once
#include <wums.h> #include "../../source/module/RelocationData.h"
#include "utils/logger.h" #include "utils/logger.h"
#include <string> #include <string>
#include <vector> #include <vector>
#include "../../source/module/RelocationData.h" #include <wums.h>
class DynamicLinkingHelper { class DynamicLinkingHelper {
public: public:

View File

@ -1,7 +1,7 @@
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include "utils/logger.h"
#include "ElfUtils.h" #include "ElfUtils.h"
#include "utils/logger.h"
// See https://github.com/decaf-emu/decaf-emu/blob/43366a34e7b55ab9d19b2444aeb0ccd46ac77dea/src/libdecaf/src/cafe/loader/cafe_loader_reloc.cpp#L144 // See https://github.com/decaf-emu/decaf-emu/blob/43366a34e7b55ab9d19b2444aeb0ccd46ac77dea/src/libdecaf/src/cafe/loader/cafe_loader_reloc.cpp#L144
bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampoline_entry_t *trampoline_data, uint32_t trampoline_data_length, bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampoline_entry_t *trampoline_data, uint32_t trampoline_data_length,
@ -10,7 +10,7 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
return true; return true;
} }
auto target = destination + offset; auto target = destination + offset;
auto value = symbol_addr + addend; auto value = symbol_addr + addend;
auto relValue = value - static_cast<uint32_t>(target); auto relValue = value - static_cast<uint32_t>(target);
@ -94,20 +94,20 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
} }
if (freeSlot == nullptr) { if (freeSlot == nullptr) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampoline data list is full\n"); DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampoline data list is full\n");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, (target - (uint32_t) &(freeSlot->trampoline[0]))); DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, (target - (uint32_t) & (freeSlot->trampoline[0])));
return false; return false;
} }
if (target - (uint32_t) &(freeSlot->trampoline[0]) > 0x1FFFFFC) { if (target - (uint32_t) & (freeSlot->trampoline[0]) > 0x1FFFFFC) {
DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer)."); DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer).");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, (target - (uint32_t) &(freeSlot->trampoline[0]))); DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, (target - (uint32_t) & (freeSlot->trampoline[0])));
return false; return false;
} }
freeSlot->trampoline[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h freeSlot->trampoline[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h
freeSlot->trampoline[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l freeSlot->trampoline[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l
freeSlot->trampoline[2] = 0x7D6903A6; // mtctr r11 freeSlot->trampoline[2] = 0x7D6903A6; // mtctr r11
freeSlot->trampoline[3] = 0x4E800420; // bctr freeSlot->trampoline[3] = 0x4E800420; // bctr
DCFlushRange((void *) freeSlot->trampoline, sizeof(freeSlot->trampoline)); DCFlushRange((void *) freeSlot->trampoline, sizeof(freeSlot->trampoline));
ICInvalidateRange((unsigned char *) freeSlot->trampoline, sizeof(freeSlot->trampoline)); ICInvalidateRange((unsigned char *) freeSlot->trampoline, sizeof(freeSlot->trampoline));
@ -117,9 +117,9 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
// Relocations for the imports may be overridden // Relocations for the imports may be overridden
freeSlot->status = RELOC_TRAMP_IMPORT_DONE; freeSlot->status = RELOC_TRAMP_IMPORT_DONE;
} }
auto symbolValue = (uint32_t) &(freeSlot->trampoline[0]); auto symbolValue = (uint32_t) & (freeSlot->trampoline[0]);
value = symbolValue + addend; value = symbolValue + addend;
distance = static_cast<int32_t>(value) - static_cast<int32_t>(target); distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
} }
} }

View File

@ -7,33 +7,33 @@
extern "C" { extern "C" {
#endif #endif
#define R_PPC_NONE 0 #define R_PPC_NONE 0
#define R_PPC_ADDR32 1 #define R_PPC_ADDR32 1
#define R_PPC_ADDR16_LO 4 #define R_PPC_ADDR16_LO 4
#define R_PPC_ADDR16_HI 5 #define R_PPC_ADDR16_HI 5
#define R_PPC_ADDR16_HA 6 #define R_PPC_ADDR16_HA 6
#define R_PPC_REL24 10 #define R_PPC_REL24 10
#define R_PPC_REL14 11 #define R_PPC_REL14 11
#define R_PPC_DTPMOD32 68 #define R_PPC_DTPMOD32 68
#define R_PPC_DTPREL32 78 #define R_PPC_DTPREL32 78
#define R_PPC_EMB_SDA21 109 #define R_PPC_EMB_SDA21 109
#define R_PPC_EMB_RELSDA 116 #define R_PPC_EMB_RELSDA 116
#define R_PPC_DIAB_SDA21_LO 180 #define R_PPC_DIAB_SDA21_LO 180
#define R_PPC_DIAB_SDA21_HI 181 #define R_PPC_DIAB_SDA21_HI 181
#define R_PPC_DIAB_SDA21_HA 182 #define R_PPC_DIAB_SDA21_HA 182
#define R_PPC_DIAB_RELSDA_LO 183 #define R_PPC_DIAB_RELSDA_LO 183
#define R_PPC_DIAB_RELSDA_HI 184 #define R_PPC_DIAB_RELSDA_HI 184
#define R_PPC_DIAB_RELSDA_HA 185 #define R_PPC_DIAB_RELSDA_HA 185
#define R_PPC_GHS_REL16_HA 251 #define R_PPC_GHS_REL16_HA 251
#define R_PPC_GHS_REL16_HI 252 #define R_PPC_GHS_REL16_HI 252
#define R_PPC_GHS_REL16_LO 253 #define R_PPC_GHS_REL16_LO 253
// Masks for manipulating Power PC relocation targets // Masks for manipulating Power PC relocation targets
#define PPC_WORD32 0xFFFFFFFF #define PPC_WORD32 0xFFFFFFFF
#define PPC_WORD30 0xFFFFFFFC #define PPC_WORD30 0xFFFFFFFC
#define PPC_LOW24 0x03FFFFFC #define PPC_LOW24 0x03FFFFFC
#define PPC_LOW14 0x0020FFFC #define PPC_LOW14 0x0020FFFC
#define PPC_HALF16 0xFFFF #define PPC_HALF16 0xFFFF
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -15,8 +15,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include "../../source/module/RelocationData.h"
#include "../../source/module/HookData.h" #include "../../source/module/HookData.h"
#include "../../source/module/RelocationData.h"
#include <vector>
#pragma once #pragma once
@ -75,11 +76,12 @@ public:
} }
bool relocationsDone = false; bool relocationsDone = false;
private: private:
std::vector<std::shared_ptr<RelocationData>> relocation_data_list; std::vector<std::shared_ptr<RelocationData>> relocation_data_list;
std::vector<std::shared_ptr<HookData>> hook_data_list; std::vector<std::shared_ptr<HookData>> hook_data_list;
std::string export_name; std::string export_name;
uint32_t entrypoint = 0; uint32_t entrypoint = 0;
bool initBeforeRelocationDoneHook = false; bool initBeforeRelocationDoneHook = false;
bool skipInitFini = false; bool skipInitFini = false;
}; };

View File

@ -22,21 +22,21 @@ std::vector<std::shared_ptr<ModuleDataMinimal>> ModuleDataPersistence::loadModul
for (int32_t i = 0; i < module_count; i++) { for (int32_t i = 0; i < module_count; i++) {
// Copy data from struct. // Copy data from struct.
module_information_single_t *module_data = &(moduleInformation->module_data[i]); module_information_single_t *module_data = &(moduleInformation->module_data[i]);
auto moduleData = std::make_shared<ModuleDataMinimal>(); auto moduleData = std::make_shared<ModuleDataMinimal>();
moduleData->setEntrypoint(module_data->entrypoint); moduleData->setEntrypoint(module_data->entrypoint);
moduleData->setInitBeforeRelocationDoneHook(module_data->initBeforeRelocationDoneHook); moduleData->setInitBeforeRelocationDoneHook(module_data->initBeforeRelocationDoneHook);
moduleData->setSkipInitFini(module_data->skipInitFini); moduleData->setSkipInitFini(module_data->skipInitFini);
moduleData->setExportName(module_data->module_export_name); moduleData->setExportName(module_data->module_export_name);
for (auto &hook_entry: module_data->hook_entries) { for (auto &hook_entry : module_data->hook_entries) {
if (hook_entry.target == 0) { if (hook_entry.target == 0) {
continue; continue;
} }
moduleData->addHookData(std::make_shared<HookData>(static_cast<wums_hook_type_t>(hook_entry.type), reinterpret_cast<const void *>(hook_entry.target))); moduleData->addHookData(std::make_shared<HookData>(static_cast<wums_hook_type_t>(hook_entry.type), reinterpret_cast<const void *>(hook_entry.target)));
} }
for (auto &linking_entry: module_data->linking_entries) { for (auto &linking_entry : module_data->linking_entries) {
if (linking_entry.destination == nullptr) { if (linking_entry.destination == nullptr) {
break; break;
} }
@ -60,7 +60,7 @@ std::vector<std::shared_ptr<ModuleDataMinimal>> ModuleDataPersistence::loadModul
continue; continue;
} }
auto rplInfo = std::make_shared<ImportRPLInformation>(importEntry->importName, importEntry->isData); auto rplInfo = std::make_shared<ImportRPLInformation>(importEntry->importName, importEntry->isData);
auto reloc = std::make_shared<RelocationData>(linking_entry.type, linking_entry.offset, linking_entry.addend, linking_entry.destination, functionEntry->functionName, rplInfo); auto reloc = std::make_shared<RelocationData>(linking_entry.type, linking_entry.offset, linking_entry.addend, linking_entry.destination, functionEntry->functionName, rplInfo);
moduleData->addRelocationData(reloc); moduleData->addRelocationData(reloc);
} }

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include <wums.h>
#include <vector>
#include "ModuleDataMinimal.h" #include "ModuleDataMinimal.h"
#include <vector>
#include <wums.h>
class ModuleDataPersistence { class ModuleDataPersistence {
public: public:

View File

@ -1,23 +1,23 @@
#include <vector>
#include <string>
#include <cstdint>
#include <coreinit/dynload.h>
#include <coreinit/cache.h>
#include <map>
#include <algorithm>
#include <coreinit/memexpheap.h>
#include "utils/logger.h"
#include "utils/memory.h"
#include "../../source/module/RelocationData.h" #include "../../source/module/RelocationData.h"
#include "ModuleDataPersistence.h"
#include "ElfUtils.h" #include "ElfUtils.h"
#include "utils/dynamic.h" #include "ModuleDataPersistence.h"
#include "globals.h" #include "globals.h"
#include "hooks.h" #include "hooks.h"
#include "utils/dynamic.h"
#include "utils/logger.h"
#include "utils/memory.h"
#include <algorithm>
#include <coreinit/cache.h>
#include <coreinit/dynload.h>
#include <coreinit/memexpheap.h>
#include <cstdint>
#include <map>
#include <string>
#include <vector>
MEMHeapHandle gHeapHandle __attribute__((section(".data"))) = nullptr; MEMHeapHandle gHeapHandle __attribute__((section(".data"))) = nullptr;
uint8_t gFunctionsPatched __attribute__((section(".data"))) = 0; uint8_t gFunctionsPatched __attribute__((section(".data"))) = 0;
uint8_t gInitCalled __attribute__((section(".data"))) = 0; uint8_t gInitCalled __attribute__((section(".data"))) = 0;
extern "C" void socket_lib_init(); extern "C" void socket_lib_init();
@ -33,7 +33,7 @@ extern "C" int _start(int argc, char **argv) {
static uint8_t ucSetupRequired = 1; static uint8_t ucSetupRequired = 1;
if (ucSetupRequired) { if (ucSetupRequired) {
gHeapHandle = MEMCreateExpHeapEx((void *) (MEMORY_REGION_USABLE_HEAP_START), MEMORY_REGION_USABLE_HEAP_END - MEMORY_REGION_USABLE_HEAP_START, 1); gHeapHandle = MEMCreateExpHeapEx((void *) (MEMORY_REGION_USABLE_HEAP_START), MEMORY_REGION_USABLE_HEAP_END - MEMORY_REGION_USABLE_HEAP_START, 1);
ucSetupRequired = 0; ucSetupRequired = 0;
} }
@ -45,14 +45,14 @@ extern "C" int _start(int argc, char **argv) {
DEBUG_FUNCTION_LINE_VERBOSE("Call real one\n"); DEBUG_FUNCTION_LINE_VERBOSE("Call real one\n");
log_deinit(); log_deinit();
return ((int (*)(int, char **)) (*(unsigned int *) 0x1005E040))(argc, argv); return ((int (*)(int, char **))(*(unsigned int *) 0x1005E040))(argc, argv);
} }
bool doRelocation(std::vector<std::shared_ptr<RelocationData>> &relocData, relocation_trampoline_entry_t *tramp_data, uint32_t tramp_length, bool skipAllocReplacement) { bool doRelocation(std::vector<std::shared_ptr<RelocationData>> &relocData, relocation_trampoline_entry_t *tramp_data, uint32_t tramp_length, bool skipAllocReplacement) {
std::map<std::string, OSDynLoad_Module> moduleCache; std::map<std::string, OSDynLoad_Module> moduleCache;
for (auto const &curReloc: relocData) { for (auto const &curReloc : relocData) {
std::string functionName = curReloc->getName(); std::string functionName = curReloc->getName();
std::string rplName = curReloc->getImportRPLInformation()->getName(); std::string rplName = curReloc->getImportRPLInformation()->getName();
uint32_t functionAddress = 0; uint32_t functionAddress = 0;
for (uint32_t i = 0; i < MAXIMUM_MODULES; i++) { for (uint32_t i = 0; i < MAXIMUM_MODULES; i++) {
@ -77,7 +77,7 @@ bool doRelocation(std::vector<std::shared_ptr<RelocationData>> &relocData, reloc
} }
if (functionAddress == 0) { if (functionAddress == 0) {
int32_t isData = curReloc->getImportRPLInformation()->isData(); int32_t isData = curReloc->getImportRPLInformation()->isData();
OSDynLoad_Module rplHandle = nullptr; OSDynLoad_Module rplHandle = nullptr;
if (moduleCache.count(rplName) == 0) { if (moduleCache.count(rplName) == 0) {
OSDynLoad_Error err = OSDynLoad_IsModuleLoaded(rplName.c_str(), &rplHandle); OSDynLoad_Error err = OSDynLoad_IsModuleLoaded(rplName.c_str(), &rplHandle);
@ -115,7 +115,7 @@ bool doRelocation(std::vector<std::shared_ptr<RelocationData>> &relocData, reloc
bool ResolveRelocations(std::vector<std::shared_ptr<ModuleDataMinimal>> &loadedModules, bool skipMemoryMappingModule) { bool ResolveRelocations(std::vector<std::shared_ptr<ModuleDataMinimal>> &loadedModules, bool skipMemoryMappingModule) {
bool wasSuccessful = true; bool wasSuccessful = true;
for (auto &curModule: loadedModules) { for (auto &curModule : loadedModules) {
DEBUG_FUNCTION_LINE_VERBOSE("Let's do the relocations for %s\n", curModule->getExportName().c_str()); DEBUG_FUNCTION_LINE_VERBOSE("Let's do the relocations for %s\n", curModule->getExportName().c_str());
if (wasSuccessful) { if (wasSuccessful) {
auto relocData = curModule->getRelocationDataList(); auto relocData = curModule->getRelocationDataList();
@ -128,11 +128,10 @@ bool ResolveRelocations(std::vector<std::shared_ptr<ModuleDataMinimal>> &loadedM
DEBUG_FUNCTION_LINE_VERBOSE("Skip alloc replace? %d\n", skipAllocFunction); DEBUG_FUNCTION_LINE_VERBOSE("Skip alloc replace? %d\n", skipAllocFunction);
if (!doRelocation(relocData, gModuleData->trampolines, DYN_LINK_TRAMPOLINE_LIST_LENGTH, skipAllocFunction)) { if (!doRelocation(relocData, gModuleData->trampolines, DYN_LINK_TRAMPOLINE_LIST_LENGTH, skipAllocFunction)) {
DEBUG_FUNCTION_LINE("FAIL\n"); DEBUG_FUNCTION_LINE("FAIL\n");
wasSuccessful = false; wasSuccessful = false;
curModule->relocationsDone = false; curModule->relocationsDone = false;
} }
curModule->relocationsDone = true; curModule->relocationsDone = true;
} }
} }
DCFlushRange((void *) MEMORY_REGION_START, MEMORY_REGION_SIZE); DCFlushRange((void *) MEMORY_REGION_START, MEMORY_REGION_SIZE);
@ -146,10 +145,10 @@ extern "C" void doStart(int argc, char **argv) {
} }
DEBUG_FUNCTION_LINE("Loading module data\n"); DEBUG_FUNCTION_LINE("Loading module data\n");
auto loadedModulesUnordered = ModuleDataPersistence::loadModuleData(gModuleData); auto loadedModulesUnordered = ModuleDataPersistence::loadModuleData(gModuleData);
auto loadedModules = OrderModulesByDependencies(loadedModulesUnordered); auto loadedModules = OrderModulesByDependencies(loadedModulesUnordered);
bool applicationEndHookLoaded = false; bool applicationEndHookLoaded = false;
for (auto &curModule: loadedModules) { for (auto &curModule : loadedModules) {
if (curModule->getExportName() == "homebrew_applicationendshook") { if (curModule->getExportName() == "homebrew_applicationendshook") {
DEBUG_FUNCTION_LINE_VERBOSE("We have ApplicationEndsHook Module!\n"); DEBUG_FUNCTION_LINE_VERBOSE("We have ApplicationEndsHook Module!\n");
applicationEndHookLoaded = true; applicationEndHookLoaded = true;
@ -158,8 +157,8 @@ extern "C" void doStart(int argc, char **argv) {
} }
// Make sure WUMS_HOOK_APPLICATION_ENDS and WUMS_HOOK_FINI_WUT are called // Make sure WUMS_HOOK_APPLICATION_ENDS and WUMS_HOOK_FINI_WUT are called
for (auto &curModule: loadedModules) { for (auto &curModule : loadedModules) {
for (auto &curHook: curModule->getHookDataList()) { for (auto &curHook : curModule->getHookDataList()) {
if (curHook->getType() == WUMS_HOOK_APPLICATION_ENDS || curHook->getType() == WUMS_HOOK_FINI_WUT_DEVOPTAB) { if (curHook->getType() == WUMS_HOOK_APPLICATION_ENDS || curHook->getType() == WUMS_HOOK_FINI_WUT_DEVOPTAB) {
if (!applicationEndHookLoaded) { if (!applicationEndHookLoaded) {
OSFatal_printf("%s requires module homebrew_applicationendshook", curModule->getExportName().c_str()); OSFatal_printf("%s requires module homebrew_applicationendshook", curModule->getExportName().c_str());
@ -175,7 +174,7 @@ extern "C" void doStart(int argc, char **argv) {
DEBUG_FUNCTION_LINE_VERBOSE("Resolve relocations without replacing alloc functions\n"); DEBUG_FUNCTION_LINE_VERBOSE("Resolve relocations without replacing alloc functions\n");
ResolveRelocations(loadedModules, true); ResolveRelocations(loadedModules, true);
for (auto &curModule: loadedModules) { for (auto &curModule : loadedModules) {
if (curModule->isInitBeforeRelocationDoneHook()) { if (curModule->isInitBeforeRelocationDoneHook()) {
CallInitHooksForModule(curModule); CallInitHooksForModule(curModule);
} }
@ -184,7 +183,7 @@ extern "C" void doStart(int argc, char **argv) {
DEBUG_FUNCTION_LINE_VERBOSE("Call Relocations done hook\n"); DEBUG_FUNCTION_LINE_VERBOSE("Call Relocations done hook\n");
CallHook(loadedModules, WUMS_HOOK_RELOCATIONS_DONE); CallHook(loadedModules, WUMS_HOOK_RELOCATIONS_DONE);
for (auto &curModule: loadedModules) { for (auto &curModule : loadedModules) {
if (!curModule->isInitBeforeRelocationDoneHook()) { if (!curModule->isInitBeforeRelocationDoneHook()) {
CallInitHooksForModule(curModule); CallInitHooksForModule(curModule);
} }
@ -200,7 +199,7 @@ extern "C" void doStart(int argc, char **argv) {
CallHook(loadedModules, WUMS_HOOK_INIT_WUT_STDCPP); CallHook(loadedModules, WUMS_HOOK_INIT_WUT_STDCPP);
CallHook(loadedModules, WUMS_HOOK_INIT_WUT_DEVOPTAB); CallHook(loadedModules, WUMS_HOOK_INIT_WUT_DEVOPTAB);
CallHook(loadedModules, WUMS_HOOK_INIT_WUT_SOCKETS); CallHook(loadedModules, WUMS_HOOK_INIT_WUT_SOCKETS);
for (auto &curModule: loadedModules) { for (auto &curModule : loadedModules) {
CallHook(curModule, WUMS_HOOK_INIT_WRAPPER, !curModule->isSkipInitFini()); CallHook(curModule, WUMS_HOOK_INIT_WRAPPER, !curModule->isSkipInitFini());
} }
CallHook(loadedModules, WUMS_HOOK_APPLICATION_STARTS); CallHook(loadedModules, WUMS_HOOK_APPLICATION_STARTS);
@ -228,9 +227,9 @@ std::vector<std::shared_ptr<ModuleDataMinimal>> OrderModulesByDependencies(const
std::vector<uint32_t> loadedModulesEntrypoints; std::vector<uint32_t> loadedModulesEntrypoints;
while (true) { while (true) {
bool canBreak = true; bool canBreak = true;
bool weDidSomething = false; bool weDidSomething = false;
for (auto const &curModule: loadedModules) { for (auto const &curModule : loadedModules) {
if (std::find(loadedModulesEntrypoints.begin(), loadedModulesEntrypoints.end(), curModule->getEntrypoint()) != loadedModulesEntrypoints.end()) { if (std::find(loadedModulesEntrypoints.begin(), loadedModulesEntrypoints.end(), curModule->getEntrypoint()) != loadedModulesEntrypoints.end()) {
// DEBUG_FUNCTION_LINE("%s [%08X] is already loaded\n", curModule->getExportName().c_str(), curModule->getEntrypoint()); // DEBUG_FUNCTION_LINE("%s [%08X] is already loaded\n", curModule->getExportName().c_str(), curModule->getEntrypoint());
continue; continue;
@ -238,7 +237,7 @@ std::vector<std::shared_ptr<ModuleDataMinimal>> OrderModulesByDependencies(const
canBreak = false; canBreak = false;
DEBUG_FUNCTION_LINE_VERBOSE("Check if we can load %s\n", curModule->getExportName().c_str()); DEBUG_FUNCTION_LINE_VERBOSE("Check if we can load %s\n", curModule->getExportName().c_str());
std::vector<std::string> importsFromOtherModules; std::vector<std::string> importsFromOtherModules;
for (const auto &curReloc: curModule->getRelocationDataList()) { for (const auto &curReloc : curModule->getRelocationDataList()) {
std::string curRPL = curReloc->getImportRPLInformation()->getName(); std::string curRPL = curReloc->getImportRPLInformation()->getName();
if (curRPL.rfind("homebrew", 0) == 0) { if (curRPL.rfind("homebrew", 0) == 0) {
if (std::find(importsFromOtherModules.begin(), importsFromOtherModules.end(), curRPL) != importsFromOtherModules.end()) { if (std::find(importsFromOtherModules.begin(), importsFromOtherModules.end(), curRPL) != importsFromOtherModules.end()) {
@ -250,7 +249,7 @@ std::vector<std::shared_ptr<ModuleDataMinimal>> OrderModulesByDependencies(const
} }
} }
bool canLoad = true; bool canLoad = true;
for (auto &curImportRPL: importsFromOtherModules) { for (auto &curImportRPL : importsFromOtherModules) {
if (std::find(loadedModulesExportNames.begin(), loadedModulesExportNames.end(), curImportRPL) != loadedModulesExportNames.end()) { if (std::find(loadedModulesExportNames.begin(), loadedModulesExportNames.end(), curImportRPL) != loadedModulesExportNames.end()) {
} else { } else {

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <cstdint>
#include "../../source/globals.h" #include "../../source/globals.h"
#include <cstdint>
extern uint32_t MemoryMappingEffectiveToPhysicalPTR; extern uint32_t MemoryMappingEffectiveToPhysicalPTR;
extern uint32_t MemoryMappingPhysicalToEffectivePTR; extern uint32_t MemoryMappingPhysicalToEffectivePTR;

View File

@ -1,8 +1,8 @@
#include <wums.h>
#include "hooks.h" #include "hooks.h"
#include "globals.h" #include "globals.h"
#include <wums.h>
static const char **hook_names = (const char *[]) { static const char **hook_names = (const char *[]){
"WUMS_HOOK_INIT_WUT_MALLOC", "WUMS_HOOK_INIT_WUT_MALLOC",
"WUMS_HOOK_FINI_WUT_MALLOC", "WUMS_HOOK_FINI_WUT_MALLOC",
"WUMS_HOOK_INIT_WUT_NEWLIB", "WUMS_HOOK_INIT_WUT_NEWLIB",
@ -21,8 +21,7 @@ static const char **hook_names = (const char *[]) {
"WUMS_HOOK_APPLICATION_STARTS", "WUMS_HOOK_APPLICATION_STARTS",
"WUMS_HOOK_APPLICATION_ENDS", "WUMS_HOOK_APPLICATION_ENDS",
"WUMS_HOOK_RELOCATIONS_DONE", "WUMS_HOOK_RELOCATIONS_DONE",
"WUMS_HOOK_APPLICATION_REQUESTS_EXIT" "WUMS_HOOK_APPLICATION_REQUESTS_EXIT"};
};
void CallHook(const std::vector<std::shared_ptr<ModuleDataMinimal>> &modules, wums_hook_type_t type, bool condition) { void CallHook(const std::vector<std::shared_ptr<ModuleDataMinimal>> &modules, wums_hook_type_t type, bool condition) {
if (condition) { if (condition) {
@ -32,7 +31,7 @@ void CallHook(const std::vector<std::shared_ptr<ModuleDataMinimal>> &modules, wu
void CallHook(const std::vector<std::shared_ptr<ModuleDataMinimal>> &modules, wums_hook_type_t type) { void CallHook(const std::vector<std::shared_ptr<ModuleDataMinimal>> &modules, wums_hook_type_t type) {
DEBUG_FUNCTION_LINE_VERBOSE("Calling hook of type %s [%d] for all modules\n", hook_names[type], type); DEBUG_FUNCTION_LINE_VERBOSE("Calling hook of type %s [%d] for all modules\n", hook_names[type], type);
for (auto &curModule: modules) { for (auto &curModule : modules) {
CallHook(curModule, type); CallHook(curModule, type);
} }
} }
@ -49,7 +48,7 @@ void CallHook(const std::shared_ptr<ModuleDataMinimal> &module, wums_hook_type_t
return; return;
} }
for (auto &curHook: module->getHookDataList()) { for (auto &curHook : module->getHookDataList()) {
auto func_ptr = (uint32_t) curHook->getTarget(); auto func_ptr = (uint32_t) curHook->getTarget();
if (func_ptr == 0) { if (func_ptr == 0) {
DEBUG_FUNCTION_LINE("Hook ptr was NULL\n"); DEBUG_FUNCTION_LINE("Hook ptr was NULL\n");
@ -70,17 +69,16 @@ void CallHook(const std::shared_ptr<ModuleDataMinimal> &module, wums_hook_type_t
type == WUMS_HOOK_INIT_WUT_SOCKETS || type == WUMS_HOOK_INIT_WUT_SOCKETS ||
type == WUMS_HOOK_FINI_WUT_SOCKETS || type == WUMS_HOOK_FINI_WUT_SOCKETS ||
type == WUMS_HOOK_INIT_WRAPPER || type == WUMS_HOOK_INIT_WRAPPER ||
type == WUMS_HOOK_FINI_WRAPPER type == WUMS_HOOK_FINI_WRAPPER)) {
)) {
DEBUG_FUNCTION_LINE_VERBOSE("Calling hook of type %s [%d] %d for %s: %08X\n", hook_names[type], type, curHook->getType(), module->getExportName().c_str(), curHook->getTarget()); DEBUG_FUNCTION_LINE_VERBOSE("Calling hook of type %s [%d] %d for %s: %08X\n", hook_names[type], type, curHook->getType(), module->getExportName().c_str(), curHook->getTarget());
((void (*)()) ((uint32_t *) func_ptr))(); ((void (*)())((uint32_t *) func_ptr))();
break; break;
} else if (type == WUMS_HOOK_INIT || } else if (type == WUMS_HOOK_INIT ||
type == WUMS_HOOK_RELOCATIONS_DONE) { type == WUMS_HOOK_RELOCATIONS_DONE) {
DEBUG_FUNCTION_LINE_VERBOSE("Calling hook of type %s [%d] %d for %s: %08X\n", hook_names[type], type, curHook->getType(), module->getExportName().c_str(), curHook->getTarget()); DEBUG_FUNCTION_LINE_VERBOSE("Calling hook of type %s [%d] %d for %s: %08X\n", hook_names[type], type, curHook->getType(), module->getExportName().c_str(), curHook->getTarget());
wums_app_init_args_t args; wums_app_init_args_t args;
args.module_information = gModuleData; args.module_information = gModuleData;
((void (*)(wums_app_init_args_t *)) ((uint32_t *) func_ptr))(&args); ((void (*)(wums_app_init_args_t *))((uint32_t *) func_ptr))(&args);
} else { } else {
DEBUG_FUNCTION_LINE("#########################################\n"); DEBUG_FUNCTION_LINE("#########################################\n");
DEBUG_FUNCTION_LINE("#########HOOK NOT IMPLEMENTED %d#########\n", type); DEBUG_FUNCTION_LINE("#########HOOK NOT IMPLEMENTED %d#########\n", type);

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include <wums.h>
#include <vector>
#include "ModuleDataMinimal.h" #include "ModuleDataMinimal.h"
#include <vector>
#include <wums.h>
void CallHook(const std::vector<std::shared_ptr<ModuleDataMinimal>> &modules, wums_hook_type_t type, bool condition); void CallHook(const std::vector<std::shared_ptr<ModuleDataMinimal>> &modules, wums_hook_type_t type, bool condition);

View File

@ -1,7 +1,7 @@
#include <coreinit/dynload.h>
#include <coreinit/debug.h> #include <coreinit/debug.h>
#include <coreinit/dynload.h>
#define IMPORT(name) void* addr_##name #define IMPORT(name) void *addr_##name
#define IMPORT_BEGIN(lib) #define IMPORT_BEGIN(lib)
#define IMPORT_END() #define IMPORT_END()
@ -11,17 +11,22 @@
#undef IMPORT_BEGIN #undef IMPORT_BEGIN
#undef IMPORT_END #undef IMPORT_END
#define IMPORT(name) do{if(OSDynLoad_FindExport(handle, 0, #name, &addr_##name) < 0)OSFatal("Function " # name " is NULL");} while(0) #define IMPORT(name) \
#define IMPORT_BEGIN(lib) do{if(OSDynLoad_IsModuleLoaded(#lib ".rpl", &handle) != OS_DYNLOAD_OK) OSFatal(#lib ".rpl is not loaded");} while(0) do { \
if (OSDynLoad_FindExport(handle, 0, #name, &addr_##name) < 0) OSFatal("Function " #name " is NULL"); \
} while (0)
#define IMPORT_BEGIN(lib) \
do { \
if (OSDynLoad_IsModuleLoaded(#lib ".rpl", &handle) != OS_DYNLOAD_OK) OSFatal(#lib ".rpl is not loaded"); \
} while (0)
#define IMPORT_END() #define IMPORT_END()
void InitFunctionPointers(void) { void InitFunctionPointers(void) {
OSDynLoad_Module handle; OSDynLoad_Module handle;
addr_OSDynLoad_Acquire = (void *) 0x0102A3B4; // 0x0200dfb4 - 0xFE3C00 addr_OSDynLoad_Acquire = (void *) 0x0102A3B4; // 0x0200dfb4 - 0xFE3C00
addr_OSDynLoad_FindExport = (void *) 0x0102B828; // 0200f428 - 0xFE3C00 addr_OSDynLoad_FindExport = (void *) 0x0102B828; // 0200f428 - 0xFE3C00
addr_OSDynLoad_IsModuleLoaded = (void *) 0x0102A59C; // 0200e19c - 0xFE3C00 addr_OSDynLoad_IsModuleLoaded = (void *) 0x0102A59C; // 0200e19c - 0xFE3C00
#include "imports.h" #include "imports.h"
} }

View File

@ -1,37 +1,37 @@
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "logger.h" #include "logger.h"
#include <coreinit/debug.h> #include <coreinit/debug.h>
#include <coreinit/systeminfo.h> #include <coreinit/systeminfo.h>
#include <coreinit/thread.h> #include <coreinit/thread.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int log_socket __attribute__((section(".data"))) = -1; static int log_socket __attribute__((section(".data"))) = -1;
static struct sockaddr_in connect_addr __attribute__((section(".data"))); static struct sockaddr_in connect_addr __attribute__((section(".data")));
static volatile int log_lock __attribute__((section(".data"))) = 0; static volatile int log_lock __attribute__((section(".data"))) = 0;
#define SOL_SOCKET -1 #define SOL_SOCKET -1
#define SOCK_DGRAM 2 #define SOCK_DGRAM 2
#define INADDR_ANY 0 #define INADDR_ANY 0
#define INADDR_BROADCAST 0xFFFFFFFF #define INADDR_BROADCAST 0xFFFFFFFF
#define PF_UNSPEC 0 #define PF_UNSPEC 0
#define PF_INET 2 #define PF_INET 2
#define PF_INET6 23 #define PF_INET6 23
#define AF_UNSPEC PF_UNSPEC #define AF_UNSPEC PF_UNSPEC
#define AF_INET PF_INET #define AF_INET PF_INET
#define AF_INET6 PF_INET6 #define AF_INET6 PF_INET6
#define IPPROTO_UDP 17 #define IPPROTO_UDP 17
#define SO_BROADCAST 0x0020 // broadcast #define SO_BROADCAST 0x0020 // broadcast
typedef uint16_t sa_family_t; typedef uint16_t sa_family_t;
@ -65,15 +65,15 @@ extern uint32_t htonl(uint32_t val);
void log_init() { void log_init() {
int broadcastEnable = 1; int broadcastEnable = 1;
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (log_socket < 0) if (log_socket < 0)
return; return;
setsockopt(log_socket, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable)); setsockopt(log_socket, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable));
memset(&connect_addr, 0, sizeof(struct sockaddr_in)); memset(&connect_addr, 0, sizeof(struct sockaddr_in));
connect_addr.sin_family = AF_INET; connect_addr.sin_family = AF_INET;
connect_addr.sin_port = 4405; connect_addr.sin_port = 4405;
connect_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); connect_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
} }
@ -102,7 +102,7 @@ void log_print(const char *str) {
int ret; int ret;
while (len > 0) { while (len > 0) {
int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet 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)); ret = sendto(log_socket, str, block, 0, (struct sockaddr *) &connect_addr, sizeof(struct sockaddr_in));
if (ret < 0) if (ret < 0)
break; break;
@ -139,4 +139,3 @@ void log_printf(const char *format, ...) {
} }
va_end(va); va_end(va);
} }

View File

@ -18,18 +18,21 @@ void log_printf(const char *format, ...);
void OSFatal_printf(const char *format, ...); void OSFatal_printf(const char *format, ...);
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) #define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__) #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__)
#define OSFATAL_FUNCTION_LINE(FMT, ARGS...)do { \ #define OSFATAL_FUNCTION_LINE(FMT, ARGS...) \
OSFatal_printf("[%s]%s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ do { \
OSFatal_printf("[%s]%s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
} while (0) } while (0)
#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \ #define DEBUG_FUNCTION_LINE(FMT, ARGS...) \
log_printf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ do { \
log_printf("[%23s]%30s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
} while (0) } while (0)
#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...)do { \ #define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) \
log_printf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ do { \
log_printf("[%23s]%30s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
} while (0) } while (0)
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -14,21 +14,21 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include <coreinit/memexpheap.h> #include "logger.h"
#include <coreinit/memdefaultheap.h>
#include <coreinit/memorymap.h>
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include <coreinit/memdefaultheap.h>
#include <coreinit/memexpheap.h>
#include <coreinit/memorymap.h>
#include <errno.h>
#include <malloc.h> #include <malloc.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include "logger.h"
extern MEMHeapHandle gHeapHandle; extern MEMHeapHandle gHeapHandle;
void *MEMAllocSafe(uint32_t size, uint32_t align) { void *MEMAllocSafe(uint32_t size, uint32_t align) {
void *res = nullptr; void *res = nullptr;
MEMHeapHandle heapHandle = gHeapHandle; MEMHeapHandle heapHandle = gHeapHandle;
res = MEMAllocFromExpHeapEx(heapHandle, size, align); res = MEMAllocFromExpHeapEx(heapHandle, size, align);
return res; return res;
} }
@ -57,9 +57,9 @@ void MemoryFree(void *ptr) {
} }
} }
uint32_t MEMAlloc __attribute__((__section__ (".data"))) = (uint32_t) MemoryAlloc; uint32_t MEMAlloc __attribute__((__section__(".data"))) = (uint32_t) MemoryAlloc;
uint32_t MEMAllocEx __attribute__((__section__ (".data"))) = (uint32_t) MemoryAllocEx; uint32_t MEMAllocEx __attribute__((__section__(".data"))) = (uint32_t) MemoryAllocEx;
uint32_t MEMFree __attribute__((__section__ (".data"))) = (uint32_t) MemoryFree; uint32_t MEMFree __attribute__((__section__(".data"))) = (uint32_t) MemoryFree;
//!------------------------------------------------------------------------------------------- //!-------------------------------------------------------------------------------------------
//! reent versions //! reent versions
@ -113,12 +113,10 @@ struct mallinfo _mallinfo_r(struct _reent *r) {
return info; return info;
} }
void void _malloc_stats_r(struct _reent *r) {
_malloc_stats_r(struct _reent *r) {
} }
int int _mallopt_r(struct _reent *r, int param, int value) {
_mallopt_r(struct _reent *r, int param, int value) {
return 0; return 0;
} }
@ -137,7 +135,6 @@ _pvalloc_r(struct _reent *r, size_t size) {
return MemoryAllocEx((size + (OS_PAGE_SIZE - 1)) & ~(OS_PAGE_SIZE - 1), OS_PAGE_SIZE); return MemoryAllocEx((size + (OS_PAGE_SIZE - 1)) & ~(OS_PAGE_SIZE - 1), OS_PAGE_SIZE);
} }
int int _malloc_trim_r(struct _reent *r, size_t pad) {
_malloc_trim_r(struct _reent *r, size_t pad) {
return 0; return 0;
} }

View File

@ -1,17 +1,17 @@
#include <coreinit/debug.h> #include "utils/logger.h"
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include <coreinit/debug.h>
#include <coreinit/memdefaultheap.h> #include <coreinit/memdefaultheap.h>
#include <whb/sdcard.h>
#include <whb/file.h> #include <whb/file.h>
#include <whb/log.h> #include <whb/log.h>
#include "utils/logger.h" #include <whb/sdcard.h>
#include "elfio/elfio.hpp"
#include "ElfUtils.h" #include "ElfUtils.h"
#include "elfio/elfio.hpp"
int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t *sizeOut) { int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t *sizeOut) {
char path[256]; char path[256];
int result = 0; int result = 0;
char *sdRootPath = nullptr; char *sdRootPath = nullptr;
if (!WHBMountSdCard()) { if (!WHBMountSdCard()) {
DEBUG_FUNCTION_LINE("Failed to mount SD Card..."); DEBUG_FUNCTION_LINE("Failed to mount SD Card...");
@ -31,13 +31,13 @@ int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t *si
goto exit; goto exit;
} }
exit: exit:
WHBUnmountSdCard(); WHBUnmountSdCard();
return result; return result;
} }
uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath) { uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath) {
char *elf_data = nullptr; char *elf_data = nullptr;
uint32_t fileSize = 0; uint32_t fileSize = 0;
if (LoadFileToMem(relativePath, &elf_data, &fileSize) != 0) { if (LoadFileToMem(relativePath, &elf_data, &fileSize) != 0) {
OSFatal("Failed to load hook_payload.elf from the SD Card."); OSFatal("Failed to load hook_payload.elf from the SD Card.");
@ -81,7 +81,7 @@ uint32_t load_loader_elf(unsigned char *baseAddress, char *elf_data, uint32_t fi
} }
uint32_t p_paddr = phdrs[i].p_paddr + (uint32_t) baseAddress; uint32_t p_paddr = phdrs[i].p_paddr + (uint32_t) baseAddress;
image = (uint8_t *) (elf_data + phdrs[i].p_offset); image = (uint8_t *) (elf_data + phdrs[i].p_offset);
memcpy((void *) p_paddr, image, phdrs[i].p_filesz); memcpy((void *) p_paddr, image, phdrs[i].p_filesz);
DCFlushRange((void *) p_paddr, phdrs[i].p_filesz); DCFlushRange((void *) p_paddr, phdrs[i].p_filesz);
@ -114,7 +114,7 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
return true; return true;
} }
auto target = destination + offset; auto target = destination + offset;
auto value = symbol_addr + addend; auto value = symbol_addr + addend;
auto relValue = value - static_cast<uint32_t>(target); auto relValue = value - static_cast<uint32_t>(target);
@ -199,19 +199,19 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
} }
if (freeSlot == nullptr) { if (freeSlot == nullptr) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampoline data list is full\n"); DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampoline data list is full\n");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, (target - (uint32_t) &(freeSlot->trampoline[0]))); DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, (target - (uint32_t) & (freeSlot->trampoline[0])));
return false; return false;
} }
if (target - (uint32_t) &(freeSlot->trampoline[0]) > 0x1FFFFFC) { if (target - (uint32_t) & (freeSlot->trampoline[0]) > 0x1FFFFFC) {
DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer)."); DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer).");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, (target - (uint32_t) &(freeSlot->trampoline[0]))); DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, (target - (uint32_t) & (freeSlot->trampoline[0])));
return false; return false;
} }
freeSlot->trampoline[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h freeSlot->trampoline[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h
freeSlot->trampoline[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l freeSlot->trampoline[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l
freeSlot->trampoline[2] = 0x7D6903A6; // mtctr r11 freeSlot->trampoline[2] = 0x7D6903A6; // mtctr r11
freeSlot->trampoline[3] = 0x4E800420; // bctr freeSlot->trampoline[3] = 0x4E800420; // bctr
DCFlushRange((void *) freeSlot->trampoline, sizeof(freeSlot->trampoline)); DCFlushRange((void *) freeSlot->trampoline, sizeof(freeSlot->trampoline));
ICInvalidateRange((unsigned char *) freeSlot->trampoline, sizeof(freeSlot->trampoline)); ICInvalidateRange((unsigned char *) freeSlot->trampoline, sizeof(freeSlot->trampoline));
@ -221,9 +221,9 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
// Relocations for the imports may be overridden // Relocations for the imports may be overridden
freeSlot->status = RELOC_TRAMP_IMPORT_DONE; freeSlot->status = RELOC_TRAMP_IMPORT_DONE;
} }
auto symbolValue = (uint32_t) &(freeSlot->trampoline[0]); auto symbolValue = (uint32_t) & (freeSlot->trampoline[0]);
value = symbolValue + addend; value = symbolValue + addend;
distance = static_cast<int32_t>(value) - static_cast<int32_t>(target); distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
} }
} }

View File

@ -12,33 +12,33 @@ int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t *si
uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath); uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath);
uint32_t load_loader_elf(unsigned char *baseAddress, char *elf_data, uint32_t fileSize); uint32_t load_loader_elf(unsigned char *baseAddress, char *elf_data, uint32_t fileSize);
#define R_PPC_NONE 0 #define R_PPC_NONE 0
#define R_PPC_ADDR32 1 #define R_PPC_ADDR32 1
#define R_PPC_ADDR16_LO 4 #define R_PPC_ADDR16_LO 4
#define R_PPC_ADDR16_HI 5 #define R_PPC_ADDR16_HI 5
#define R_PPC_ADDR16_HA 6 #define R_PPC_ADDR16_HA 6
#define R_PPC_REL24 10 #define R_PPC_REL24 10
#define R_PPC_REL14 11 #define R_PPC_REL14 11
#define R_PPC_DTPMOD32 68 #define R_PPC_DTPMOD32 68
#define R_PPC_DTPREL32 78 #define R_PPC_DTPREL32 78
#define R_PPC_EMB_SDA21 109 #define R_PPC_EMB_SDA21 109
#define R_PPC_EMB_RELSDA 116 #define R_PPC_EMB_RELSDA 116
#define R_PPC_DIAB_SDA21_LO 180 #define R_PPC_DIAB_SDA21_LO 180
#define R_PPC_DIAB_SDA21_HI 181 #define R_PPC_DIAB_SDA21_HI 181
#define R_PPC_DIAB_SDA21_HA 182 #define R_PPC_DIAB_SDA21_HA 182
#define R_PPC_DIAB_RELSDA_LO 183 #define R_PPC_DIAB_RELSDA_LO 183
#define R_PPC_DIAB_RELSDA_HI 184 #define R_PPC_DIAB_RELSDA_HI 184
#define R_PPC_DIAB_RELSDA_HA 185 #define R_PPC_DIAB_RELSDA_HA 185
#define R_PPC_GHS_REL16_HA 251 #define R_PPC_GHS_REL16_HA 251
#define R_PPC_GHS_REL16_HI 252 #define R_PPC_GHS_REL16_HI 252
#define R_PPC_GHS_REL16_LO 253 #define R_PPC_GHS_REL16_LO 253
// Masks for manipulating Power PC relocation targets // Masks for manipulating Power PC relocation targets
#define PPC_WORD32 0xFFFFFFFF #define PPC_WORD32 0xFFFFFFFF
#define PPC_WORD30 0xFFFFFFFC #define PPC_WORD30 0xFFFFFFFC
#define PPC_LOW24 0x03FFFFFC #define PPC_LOW24 0x03FFFFFC
#define PPC_LOW14 0x0020FFFC #define PPC_LOW14 0x0020FFFC
#define PPC_HALF16 0xFFFF #define PPC_HALF16 0xFFFF
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,3 +1,4 @@
// clang-format off
/* /*
Copyright (C) 2001-2015 by Serge Lamikhov-Center Copyright (C) 2001-2015 by Serge Lamikhov-Center

View File

@ -1,3 +1,4 @@
// clang-format off
/* /*
Copyright (C) 2001-2015 by Serge Lamikhov-Center Copyright (C) 2001-2015 by Serge Lamikhov-Center

View File

@ -1,3 +1,4 @@
// clang-format off
/* /*
Copyright (C) 2001-2015 by Serge Lamikhov-Center Copyright (C) 2001-2015 by Serge Lamikhov-Center

View File

@ -1,3 +1,4 @@
// clang-format off
/* /*
Copyright (C) 2001-2015 by Serge Lamikhov-Center Copyright (C) 2001-2015 by Serge Lamikhov-Center

View File

@ -1,3 +1,4 @@
// clang-format off
/* /*
Copyright (C) 2001-2015 by Serge Lamikhov-Center Copyright (C) 2001-2015 by Serge Lamikhov-Center

View File

@ -1,3 +1,4 @@
// clang-format off
/* /*
Copyright (C) 2001-2015 by Serge Lamikhov-Center Copyright (C) 2001-2015 by Serge Lamikhov-Center

View File

@ -1,3 +1,4 @@
// clang-format off
/* /*
Copyright (C) 2001-2015 by Serge Lamikhov-Center Copyright (C) 2001-2015 by Serge Lamikhov-Center

View File

@ -1,3 +1,4 @@
// clang-format off
/* /*
Copyright (C) 2001-2015 by Serge Lamikhov-Center Copyright (C) 2001-2015 by Serge Lamikhov-Center

View File

@ -1,3 +1,4 @@
// clang-format off
/* /*
Copyright (C) 2001-2015 by Serge Lamikhov-Center Copyright (C) 2001-2015 by Serge Lamikhov-Center

View File

@ -1,3 +1,4 @@
// clang-format off
/* /*
Copyright (C) 2001-2015 by Serge Lamikhov-Center Copyright (C) 2001-2015 by Serge Lamikhov-Center

View File

@ -1,3 +1,4 @@
// clang-format off
/* /*
Copyright (C) 2001-2015 by Serge Lamikhov-Center Copyright (C) 2001-2015 by Serge Lamikhov-Center

View File

@ -1,3 +1,4 @@
// clang-format off
/* /*
Copyright (C) 2001-2015 by Serge Lamikhov-Center Copyright (C) 2001-2015 by Serge Lamikhov-Center

View File

@ -1,15 +1,15 @@
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <fs/CFile.hpp> #include <fs/CFile.hpp>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
CFile::CFile() { CFile::CFile() {
iFd = -1; iFd = -1;
mem_file = NULL; mem_file = NULL;
filesize = 0; filesize = 0;
pos = 0; pos = 0;
} }
CFile::CFile(const std::string &filepath, eOpenTypes mode) { CFile::CFile(const std::string &filepath, eOpenTypes mode) {
@ -35,7 +35,7 @@ int32_t CFile::open(const std::string &filepath, eOpenTypes mode) {
switch (mode) { switch (mode) {
default: default:
case ReadOnly: // file must exist case ReadOnly: // file must exist
openMode = O_RDONLY; openMode = O_RDONLY;
break; break;
case WriteOnly: // file will be created / zerod case WriteOnly: // file will be created / zerod
@ -77,10 +77,10 @@ void CFile::close() {
if (iFd >= 0) if (iFd >= 0)
::close(iFd); ::close(iFd);
iFd = -1; iFd = -1;
mem_file = NULL; mem_file = NULL;
filesize = 0; filesize = 0;
pos = 0; pos = 0;
} }
int32_t CFile::read(uint8_t *ptr, size_t size) { int32_t CFile::read(uint8_t *ptr, size_t size) {
@ -127,7 +127,7 @@ int32_t CFile::write(const uint8_t *ptr, size_t size) {
} }
int32_t CFile::seek(long int offset, int32_t origin) { int32_t CFile::seek(long int offset, int32_t origin) {
int32_t ret = 0; int32_t ret = 0;
int64_t newPos = pos; int64_t newPos = pos;
if (origin == SEEK_SET) { if (origin == SEEK_SET) {
@ -158,7 +158,7 @@ int32_t CFile::seek(long int offset, int32_t origin) {
int32_t CFile::fwrite(const char *format, ...) { int32_t CFile::fwrite(const char *format, ...) {
char tmp[512]; char tmp[512];
tmp[0] = 0; tmp[0] = 0;
int32_t result = -1; int32_t result = -1;
va_list va; va_list va;
@ -171,5 +171,3 @@ int32_t CFile::fwrite(const char *format, ...) {
return result; return result;
} }

View File

@ -1,10 +1,10 @@
#ifndef CFILE_HPP_ #ifndef CFILE_HPP_
#define CFILE_HPP_ #define CFILE_HPP_
#include <stdio.h>
#include <string>
#include <string.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <unistd.h> #include <unistd.h>
#include <wut_types.h> #include <wut_types.h>

View File

@ -24,22 +24,22 @@
* DirList Class * DirList Class
* for WiiXplorer 2010 * for WiiXplorer 2010
***************************************************************************/ ***************************************************************************/
#include <algorithm>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <string> #include <string>
#include <strings.h> #include <strings.h>
#include <algorithm>
#include <sys/stat.h>
#include <sys/dirent.h> #include <sys/dirent.h>
#include <sys/stat.h>
#include <fs/DirList.h> #include <fs/DirList.h>
#include <utils/StringTools.h> #include <utils/StringTools.h>
DirList::DirList() { DirList::DirList() {
Flags = 0; Flags = 0;
Filter = 0; Filter = 0;
Depth = 0; Depth = 0;
} }
DirList::DirList(const std::string &path, const char *filter, uint32_t flags, uint32_t maxDepth) { DirList::DirList(const std::string &path, const char *filter, uint32_t flags, uint32_t maxDepth) {
@ -55,9 +55,9 @@ BOOL DirList::LoadPath(const std::string &folder, const char *filter, uint32_t f
if (folder.empty()) if (folder.empty())
return false; return false;
Flags = flags; Flags = flags;
Filter = filter; Filter = filter;
Depth = maxDepth; Depth = maxDepth;
std::string folderpath(folder); std::string folderpath(folder);
uint32_t length = folderpath.size(); uint32_t length = folderpath.size();
@ -82,14 +82,14 @@ BOOL DirList::InternalLoadPath(std::string &folderpath) {
return false; return false;
struct dirent *dirent = NULL; struct dirent *dirent = NULL;
DIR *dir = NULL; DIR *dir = NULL;
dir = opendir(folderpath.c_str()); dir = opendir(folderpath.c_str());
if (dir == NULL) if (dir == NULL)
return false; return false;
while ((dirent = readdir(dir)) != 0) { while ((dirent = readdir(dir)) != 0) {
BOOL isDir = dirent->d_type & DT_DIR; BOOL isDir = dirent->d_type & DT_DIR;
const char *filename = dirent->d_name; const char *filename = dirent->d_name;
if (isDir) { if (isDir) {

View File

@ -27,8 +27,8 @@
#ifndef ___DIRLIST_H_ #ifndef ___DIRLIST_H_
#define ___DIRLIST_H_ #define ___DIRLIST_H_
#include <vector>
#include <string> #include <string>
#include <vector>
#include <wut_types.h> #include <wut_types.h>
typedef struct { typedef struct {
@ -93,10 +93,11 @@ public:
//! Enum for search/filter flags //! Enum for search/filter flags
enum { enum {
Files = 0x01, Files = 0x01,
Dirs = 0x02, Dirs = 0x02,
CheckSubfolders = 0x08, CheckSubfolders = 0x08,
}; };
protected: protected:
// Internal parser // Internal parser
BOOL InternalLoadPath(std::string &path); BOOL InternalLoadPath(std::string &path);

View File

@ -3,13 +3,13 @@
#include <cstdint> #include <cstdint>
#include <wums/defines/module_defines.h> #include <wums/defines/module_defines.h>
#define MEMORY_REGION_START 0x00800000 #define MEMORY_REGION_START 0x00800000
#define MEMORY_REGION_SIZE 0x00800000 #define MEMORY_REGION_SIZE 0x00800000
#define MEMORY_REGION_USABLE_HEAP_START (MEMORY_REGION_START + 0x00080000) // We don't want to override the relocator #define MEMORY_REGION_USABLE_HEAP_START (MEMORY_REGION_START + 0x00080000) // We don't want to override the relocator
#define MEMORY_REGION_USABLE_HEAP_END (MEMORY_REGION_USABLE_HEAP_START + 0x00080000) // heap size is 512 KiB for now #define MEMORY_REGION_USABLE_HEAP_END (MEMORY_REGION_USABLE_HEAP_START + 0x00080000) // heap size is 512 KiB for now
#define MEMORY_REGION_USABLE_START MEMORY_REGION_USABLE_HEAP_END #define MEMORY_REGION_USABLE_START MEMORY_REGION_USABLE_HEAP_END
#define MEMORY_REGION_USABLE_END 0x00FFF000 // The last 0x1000 bytes are reserved kernel hook #define MEMORY_REGION_USABLE_END 0x00FFF000 // The last 0x1000 bytes are reserved kernel hook
#define gModuleData ((module_information_t *) (MEMORY_REGION_USABLE_START)) #define gModuleData ((module_information_t *) (MEMORY_REGION_USABLE_START))

View File

@ -1,6 +1,6 @@
#include "kernel.h" #include "kernel.h"
#include "relocator_elf.h"
#include "ElfUtils.h" #include "ElfUtils.h"
#include "relocator_elf.h"
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include <coreinit/memorymap.h> #include <coreinit/memorymap.h>
@ -37,23 +37,22 @@ void KernelWriteU32(uint32_t addr, uint32_t value) {
} }
/* Write a 32-bit word with kernel permissions */ /* Write a 32-bit word with kernel permissions */
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) { void __attribute__((noinline)) kern_write(void *addr, uint32_t value) {
asm volatile ( asm volatile(
"li 3,1\n" "li 3,1\n"
"li 4,0\n" "li 4,0\n"
"mr 5,%1\n" "mr 5,%1\n"
"li 6,0\n" "li 6,0\n"
"li 7,0\n" "li 7,0\n"
"lis 8,1\n" "lis 8,1\n"
"mr 9,%0\n" "mr 9,%0\n"
"mr %1,1\n" "mr %1,1\n"
"li 0,0x3500\n" "li 0,0x3500\n"
"sc\n" "sc\n"
"nop\n" "nop\n"
"mr 1,%1\n" "mr 1,%1\n"
: :
: "r"(addr), "r"(value) : "r"(addr), "r"(value)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12" "11", "12");
);
} }

View File

@ -2,16 +2,16 @@
#include <stdint.h> #include <stdint.h>
#define ADDRESS_main_entry_hook 0x0101C56C #define ADDRESS_main_entry_hook 0x0101C56C
#define KERN_SYSCALL_TBL_1 0xFFE84C70 // unknown #define KERN_SYSCALL_TBL_1 0xFFE84C70 // unknown
#define KERN_SYSCALL_TBL_2 0xFFE85070 // works with games #define KERN_SYSCALL_TBL_2 0xFFE85070 // works with games
#define KERN_SYSCALL_TBL_3 0xFFE85470 // works with loader #define KERN_SYSCALL_TBL_3 0xFFE85470 // works with loader
#define KERN_SYSCALL_TBL_4 0xFFEAAA60 // works with home menu #define KERN_SYSCALL_TBL_4 0xFFEAAA60 // works with home menu
#define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL) #define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL)
void SetupRelocator(); void SetupRelocator();
void KernelWriteU32(uint32_t addr, uint32_t value); void KernelWriteU32(uint32_t addr, uint32_t value);
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value); void __attribute__((noinline)) kern_write(void *addr, uint32_t value);

View File

@ -1,15 +1,15 @@
#include <cstring> #include <cstring>
#include <elfio/elfio.hpp> #include <elfio/elfio.hpp>
#include <sysapp/launch.h>
#include <nn/act/client_cpp.h> #include <nn/act/client_cpp.h>
#include <sysapp/launch.h>
#include "fs/DirList.h"
#include "module/ModuleDataPersistence.h"
#include "module/ModuleDataFactory.h"
#include "ElfUtils.h" #include "ElfUtils.h"
#include "kernel.h" #include "fs/DirList.h"
#include "globals.h" #include "globals.h"
#include "kernel.h"
#include "module/ModuleDataFactory.h"
#include "module/ModuleDataPersistence.h"
extern "C" uint32_t textStart(); extern "C" uint32_t textStart();
extern "C" void __fini(); extern "C" void __fini();
@ -48,7 +48,7 @@ int main(int argc, char **argv) {
SetupRelocator(); SetupRelocator();
nn::act::Initialize(); nn::act::Initialize();
nn::act::SlotNo slot = nn::act::GetSlotNo(); nn::act::SlotNo slot = nn::act::GetSlotNo();
nn::act::SlotNo defaultSlot = nn::act::GetDefaultAccount(); nn::act::SlotNo defaultSlot = nn::act::GetDefaultAccount();
nn::act::Finalize(); nn::act::Finalize();

View File

@ -1,9 +1,9 @@
#include "DynamicLinkingHelper.h" #include "DynamicLinkingHelper.h"
#include "utils/logger.h"
#include <coreinit/dynload.h>
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
#include <vector> #include <vector>
#include <coreinit/dynload.h>
#include "utils/logger.h"
dyn_linking_function_t *DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName) { dyn_linking_function_t *DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName) {
if (data == nullptr) { if (data == nullptr) {
@ -13,7 +13,7 @@ dyn_linking_function_t *DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_li
return nullptr; return nullptr;
} }
dyn_linking_function_t *result = nullptr; dyn_linking_function_t *result = nullptr;
for (auto &function: data->functions) { for (auto &function : data->functions) {
dyn_linking_function_t *curEntry = &function; dyn_linking_function_t *curEntry = &function;
if (strlen(curEntry->functionName) == 0) { if (strlen(curEntry->functionName) == 0) {
if (strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) { if (strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) {
@ -45,7 +45,7 @@ dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocatio
return nullptr; return nullptr;
} }
dyn_linking_import_t *result = nullptr; dyn_linking_import_t *result = nullptr;
for (auto &import: data->imports) { for (auto &import : data->imports) {
dyn_linking_import_t *curEntry = &import; dyn_linking_import_t *curEntry = &import;
if (strlen(curEntry->importName) == 0) { if (strlen(curEntry->importName) == 0) {
if (strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) { if (strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) {
@ -54,7 +54,7 @@ dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocatio
} }
strncpy(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH); strncpy(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH);
curEntry->isData = isData; curEntry->isData = isData;
result = curEntry; result = curEntry;
break; break;
} }
if (strncmp(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH) == 0 && (curEntry->isData == isData)) { if (strncmp(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH) == 0 && (curEntry->isData == isData)) {
@ -98,12 +98,12 @@ bool DynamicLinkingHelper::addRelocationEntry(dyn_linking_relocation_entry_t *li
if (curEntry->functionEntry != nullptr) { if (curEntry->functionEntry != nullptr) {
continue; continue;
} }
curEntry->type = type; curEntry->type = type;
curEntry->offset = offset; curEntry->offset = offset;
curEntry->addend = addend; curEntry->addend = addend;
curEntry->destination = destination; curEntry->destination = destination;
curEntry->functionEntry = functionName; curEntry->functionEntry = functionName;
curEntry->importEntry = importInfo; curEntry->importEntry = importInfo;
return true; return true;
} }

View File

@ -1,10 +1,10 @@
#pragma once #pragma once
#include <wums.h> #include "RelocationData.h"
#include "utils/logger.h" #include "utils/logger.h"
#include <string> #include <string>
#include <vector> #include <vector>
#include "RelocationData.h" #include <wums.h>
class DynamicLinkingHelper { class DynamicLinkingHelper {
public: public:

View File

@ -1,13 +1,14 @@
#pragma once #pragma once
#include <string>
#include <wums.h> #include <wums.h>
class ExportData { class ExportData {
public: public:
ExportData(wums_entry_type_t type, const std::string &name, const void *address) { ExportData(wums_entry_type_t type, const std::string &name, const void *address) {
this->type = type; this->type = type;
this->name = name; this->name = name;
this->address = address; this->address = address;
} }

View File

@ -24,16 +24,15 @@ class FunctionSymbolData {
public: public:
FunctionSymbolData(const FunctionSymbolData &o2) = default; FunctionSymbolData(const FunctionSymbolData &o2) = default;
FunctionSymbolData(const char *name, void *address, uint32_t size) : FunctionSymbolData(const char *name, void *address, uint32_t size) : name(name),
name(name), address(address),
address(address), size(size) {
size(size) {
} }
virtual ~FunctionSymbolData() = default; virtual ~FunctionSymbolData() = default;
bool operator<(const FunctionSymbolData &rhs) const { bool operator<(const FunctionSymbolData &rhs) const {
return (uint32_t) address < (uint32_t) rhs.address; //assume that you compare the record based on a return (uint32_t) address < (uint32_t) rhs.address; //assume that you compare the record based on a
} }
[[nodiscard]] const char *getName() const { [[nodiscard]] const char *getName() const {

View File

@ -5,7 +5,7 @@
class HookData { class HookData {
public: public:
HookData(wums_hook_type_t type, const void *target) { HookData(wums_hook_type_t type, const void *target) {
this->type = type; this->type = type;
this->target = target; this->target = target;
} }

View File

@ -17,16 +17,17 @@
#pragma once #pragma once
#include <string>
#include <optional>
#include <utility>
#include "utils/logger.h" #include "utils/logger.h"
#include <memory>
#include <optional>
#include <string>
#include <utility>
class ImportRPLInformation { class ImportRPLInformation {
public: public:
explicit ImportRPLInformation(std::string name, bool isData = false) { explicit ImportRPLInformation(std::string name, bool isData = false) {
this->name = std::move(name); this->name = std::move(name);
this->_isData = isData; this->_isData = isData;
} }
@ -46,7 +47,7 @@ public:
rplName = rawSectionName.substr(fimport.size()); rplName = rawSectionName.substr(fimport.size());
} else if (std::equal(dimport.begin(), dimport.end(), rawSectionName.begin())) { } else if (std::equal(dimport.begin(), dimport.end(), rawSectionName.begin())) {
rplName = rawSectionName.substr(dimport.size()); rplName = rawSectionName.substr(dimport.size());
data = true; data = true;
} else { } else {
DEBUG_FUNCTION_LINE("invalid section name\n"); DEBUG_FUNCTION_LINE("invalid section name\n");
return std::nullopt; return std::nullopt;

View File

@ -3,7 +3,7 @@
std::string ModuleData::toString() const { std::string ModuleData::toString() const {
std::string res = StringTools::strfmt("Entrypoint %08X, bss: %08X (%d), bss: %08X (%d)\n", getEntrypoint(), getBSSAddr(), getBSSSize(), getSBSSAddr(), getSBSSSize()); std::string res = StringTools::strfmt("Entrypoint %08X, bss: %08X (%d), bss: %08X (%d)\n", getEntrypoint(), getBSSAddr(), getBSSSize(), getSBSSAddr(), getSBSSSize());
for (auto const &reloc: relocation_data_list) { for (auto const &reloc : relocation_data_list) {
res += reloc->toString(); res += reloc->toString();
} }
return res; return res;

View File

@ -17,15 +17,15 @@
#pragma once #pragma once
#include <string> #include "ExportData.h"
#include <vector> #include "FunctionSymbolData.h"
#include <map> #include "HookData.h"
#include <set>
#include "RelocationData.h" #include "RelocationData.h"
#include "SectionInfo.h" #include "SectionInfo.h"
#include "ExportData.h" #include <map>
#include "HookData.h" #include <set>
#include "FunctionSymbolData.h" #include <string>
#include <vector>
struct FunctionSymbolDataComparator { struct FunctionSymbolDataComparator {
bool operator()(const std::shared_ptr<FunctionSymbolData> &lhs, bool operator()(const std::shared_ptr<FunctionSymbolData> &lhs,
@ -164,6 +164,7 @@ public:
} }
bool relocationsDone = false; bool relocationsDone = false;
private: private:
std::vector<std::shared_ptr<RelocationData>> relocation_data_list; std::vector<std::shared_ptr<RelocationData>> relocation_data_list;
std::vector<std::shared_ptr<ExportData>> export_data_list; std::vector<std::shared_ptr<ExportData>> export_data_list;
@ -173,13 +174,13 @@ private:
std::string export_name; std::string export_name;
uint32_t bssAddr = 0; uint32_t bssAddr = 0;
uint32_t bssSize = 0; uint32_t bssSize = 0;
uint32_t sbssAddr = 0; uint32_t sbssAddr = 0;
uint32_t sbssSize = 0; uint32_t sbssSize = 0;
uint32_t startAddress = 0; uint32_t startAddress = 0;
uint32_t endAddress = 0; uint32_t endAddress = 0;
uint32_t entrypoint = 0; uint32_t entrypoint = 0;
bool initBeforeRelocationDoneHook = false; bool initBeforeRelocationDoneHook = false;
bool skipInitFini = false; bool skipInitFini = false;
}; };

View File

@ -15,15 +15,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include <string>
#include <vector>
#include <map>
#include <coreinit/cache.h>
#include <wums.h>
#include "ModuleDataFactory.h" #include "ModuleDataFactory.h"
#include "utils/utils.h"
#include "ElfUtils.h" #include "ElfUtils.h"
#include "FunctionSymbolData.h" #include "FunctionSymbolData.h"
#include "utils/utils.h"
#include <coreinit/cache.h>
#include <map>
#include <string>
#include <vector>
#include <wums.h>
using namespace ELFIO; using namespace ELFIO;
@ -49,7 +49,7 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p
uint32_t entrypoint = offset_text + (uint32_t) reader.get_entry() - 0x02000000; uint32_t entrypoint = offset_text + (uint32_t) reader.get_entry() - 0x02000000;
uint32_t totalSize = 0; uint32_t totalSize = 0;
uint32_t endAddress = 0; uint32_t endAddress = 0;
for (uint32_t i = 0; i < sec_num; ++i) { for (uint32_t i = 0; i < sec_num; ++i) {
@ -133,18 +133,18 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p
} }
auto relocationData = getImportRelocationData(reader, destinations); auto relocationData = getImportRelocationData(reader, destinations);
for (auto const &reloc: relocationData) { for (auto const &reloc : relocationData) {
moduleData->addRelocationData(reloc); moduleData->addRelocationData(reloc);
} }
auto secInfo = moduleData->getSectionInfo(".wums.exports"); auto secInfo = moduleData->getSectionInfo(".wums.exports");
if (secInfo && secInfo.value()->getSize() > 0) { if (secInfo && secInfo.value()->getSize() > 0) {
size_t entries_count = secInfo.value()->getSize() / sizeof(wums_entry_t); size_t entries_count = secInfo.value()->getSize() / sizeof(wums_entry_t);
auto *entries = (wums_entry_t *) secInfo.value()->getAddress(); auto *entries = (wums_entry_t *) secInfo.value()->getAddress();
if (entries != nullptr) { if (entries != nullptr) {
for (size_t j = 0; j < entries_count; j++) { for (size_t j = 0; j < entries_count; j++) {
wums_entry_t *exp = &entries[j]; wums_entry_t *exp = &entries[j];
DEBUG_FUNCTION_LINE("Saving export of type %08X, name %s, target: %08X"/*,pluginData.getPluginInformation()->getName().c_str()*/, exp->type, exp->name, (void *) exp->address); DEBUG_FUNCTION_LINE("Saving export of type %08X, name %s, target: %08X" /*,pluginData.getPluginInformation()->getName().c_str()*/, exp->type, exp->name, (void *) exp->address);
auto exportData = std::make_shared<ExportData>(exp->type, exp->name, exp->address); auto exportData = std::make_shared<ExportData>(exp->type, exp->name, exp->address);
moduleData->addExportData(exportData); moduleData->addExportData(exportData);
} }
@ -154,11 +154,11 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p
secInfo = moduleData->getSectionInfo(".wums.hooks"); secInfo = moduleData->getSectionInfo(".wums.hooks");
if (secInfo && secInfo.value()->getSize() > 0) { if (secInfo && secInfo.value()->getSize() > 0) {
size_t entries_count = secInfo.value()->getSize() / sizeof(wums_hook_t); size_t entries_count = secInfo.value()->getSize() / sizeof(wums_hook_t);
auto *hooks = (wums_hook_t *) secInfo.value()->getAddress(); auto *hooks = (wums_hook_t *) secInfo.value()->getAddress();
if (hooks != nullptr) { if (hooks != nullptr) {
for (size_t j = 0; j < entries_count; j++) { for (size_t j = 0; j < entries_count; j++) {
wums_hook_t *hook = &hooks[j]; wums_hook_t *hook = &hooks[j];
DEBUG_FUNCTION_LINE("Saving hook of type %08X, target: %08X"/*,pluginData.getPluginInformation()->getName().c_str()*/, hook->type, hook->target); DEBUG_FUNCTION_LINE("Saving hook of type %08X, target: %08X" /*,pluginData.getPluginInformation()->getName().c_str()*/, hook->type, hook->target);
auto hookData = std::make_shared<HookData>(hook->type, hook->target); auto hookData = std::make_shared<HookData>(hook->type, hook->target);
moduleData->addHookData(hookData); moduleData->addHookData(hookData);
} }
@ -212,7 +212,7 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p
} }
} }
char *strTable = (char *) endAddress; char *strTable = (char *) endAddress;
uint32_t strOffset = 0; uint32_t strOffset = 0;
// Get the symbol for functions. // Get the symbol for functions.
@ -225,16 +225,16 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p
if (sym_no > 0) { if (sym_no > 0) {
for (Elf_Half j = 0; j < sym_no; ++j) { for (Elf_Half j = 0; j < sym_no; ++j) {
std::string name; std::string name;
Elf64_Addr value = 0; Elf64_Addr value = 0;
Elf_Xword size = 0; Elf_Xword size = 0;
unsigned char bind = 0; unsigned char bind = 0;
unsigned char type = 0; unsigned char type = 0;
Elf_Half section = 0; Elf_Half section = 0;
unsigned char other = 0; unsigned char other = 0;
if (symbols.get_symbol(j, name, value, size, bind, type, section, other)) { if (symbols.get_symbol(j, name, value, size, bind, type, section, other)) {
if (type == STT_FUNC) { // We only care about functions. if (type == STT_FUNC) { // We only care about functions.
auto sectionVal = reader.sections[section]; auto sectionVal = reader.sections[section];
auto offsetVal = value - sectionVal->get_address(); auto offsetVal = value - sectionVal->get_address();
auto sectionOpt = moduleData->getSectionInfo(sectionVal->get_name()); auto sectionOpt = moduleData->getSectionInfo(sectionVal->get_name());
if (!sectionOpt.has_value()) { if (!sectionOpt.has_value()) {
continue; continue;

View File

@ -17,12 +17,12 @@
#pragma once #pragma once
#include <string>
#include <vector>
#include <map>
#include <wums.h>
#include "ModuleData.h" #include "ModuleData.h"
#include "elfio/elfio.hpp" #include "elfio/elfio.hpp"
#include <map>
#include <string>
#include <vector>
#include <wums.h>
class ModuleDataFactory { class ModuleDataFactory {
public: public:

View File

@ -1,6 +1,6 @@
#include <coreinit/cache.h>
#include "ModuleDataPersistence.h" #include "ModuleDataPersistence.h"
#include "DynamicLinkingHelper.h" #include "DynamicLinkingHelper.h"
#include <coreinit/cache.h>
bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformation, const std::shared_ptr<ModuleData> &module) { bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformation, const std::shared_ptr<ModuleData> &module) {
int32_t module_count = moduleInformation->number_used_modules; int32_t module_count = moduleInformation->number_used_modules;
@ -15,7 +15,7 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati
DEBUG_FUNCTION_LINE("Saving relocation data for module at %08X", module->getEntrypoint()); DEBUG_FUNCTION_LINE("Saving relocation data for module at %08X", module->getEntrypoint());
// Relocation // Relocation
auto relocationData = module->getRelocationDataList(); auto relocationData = module->getRelocationDataList();
for (auto const &reloc: relocationData) { for (auto const &reloc : relocationData) {
if (!DynamicLinkingHelper::addRelocationEntry(&(moduleInformation->linking_data), module_data->linking_entries, if (!DynamicLinkingHelper::addRelocationEntry(&(moduleInformation->linking_data), module_data->linking_entries,
DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) { DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) {
DEBUG_FUNCTION_LINE("Failed to add relocation entry\n"); DEBUG_FUNCTION_LINE("Failed to add relocation entry\n");
@ -24,15 +24,15 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati
} }
auto exportData = module->getExportDataList(); auto exportData = module->getExportDataList();
for (auto const &curExport: exportData) { for (auto const &curExport : exportData) {
bool found = false; bool found = false;
for (auto &export_entry: module_data->export_entries) { for (auto &export_entry : module_data->export_entries) {
if (export_entry.address == 0) { if (export_entry.address == 0) {
export_entry.type = curExport->getType(); export_entry.type = curExport->getType();
export_entry.name[0] = '\0'; export_entry.name[0] = '\0';
strncat(export_entry.name, curExport->getName().c_str(), sizeof(export_entry.name) - 1); strncat(export_entry.name, curExport->getName().c_str(), sizeof(export_entry.name) - 1);
export_entry.address = (uint32_t) curExport->getAddress(); export_entry.address = (uint32_t) curExport->getAddress();
found = true; found = true;
break; break;
} }
} }
@ -43,13 +43,13 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati
} }
auto hookData = module->getHookDataList(); auto hookData = module->getHookDataList();
for (auto const &curHook: hookData) { for (auto const &curHook : hookData) {
bool found = false; bool found = false;
for (auto &hook_entry: module_data->hook_entries) { for (auto &hook_entry : module_data->hook_entries) {
if (hook_entry.target == 0) { if (hook_entry.target == 0) {
hook_entry.type = curHook->getType(); hook_entry.type = curHook->getType();
hook_entry.target = (uint32_t) curHook->getTarget(); hook_entry.target = (uint32_t) curHook->getTarget();
found = true; found = true;
break; break;
} }
} }
@ -63,36 +63,36 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati
uint32_t entryCount = module->getFunctionSymbolDataList().size(); uint32_t entryCount = module->getFunctionSymbolDataList().size();
if (entryCount > 0) { if (entryCount > 0) {
auto ptr = &moduleInformation->function_symbols[moduleInformation->number_used_function_symbols]; auto ptr = &moduleInformation->function_symbols[moduleInformation->number_used_function_symbols];
module_data->function_symbol_entries = ptr; module_data->function_symbol_entries = ptr;
uint32_t sym_offset = 0; uint32_t sym_offset = 0;
for (auto &curFuncSym: module->getFunctionSymbolDataList()) { for (auto &curFuncSym : module->getFunctionSymbolDataList()) {
if (moduleInformation->number_used_function_symbols >= FUNCTION_SYMBOL_LIST_LENGTH) { if (moduleInformation->number_used_function_symbols >= FUNCTION_SYMBOL_LIST_LENGTH) {
DEBUG_FUNCTION_LINE("Function symbol list is full"); DEBUG_FUNCTION_LINE("Function symbol list is full");
break; break;
} }
module_data->function_symbol_entries[sym_offset].address = curFuncSym->getAddress(); module_data->function_symbol_entries[sym_offset].address = curFuncSym->getAddress();
module_data->function_symbol_entries[sym_offset].name = (char *) curFuncSym->getName(); module_data->function_symbol_entries[sym_offset].name = (char *) curFuncSym->getName();
module_data->function_symbol_entries[sym_offset].size = curFuncSym->getSize(); module_data->function_symbol_entries[sym_offset].size = curFuncSym->getSize();
sym_offset++; sym_offset++;
moduleInformation->number_used_function_symbols++; moduleInformation->number_used_function_symbols++;
} }
module_data->number_used_function_symbols = sym_offset; module_data->number_used_function_symbols = sym_offset;
} else { } else {
module_data->function_symbol_entries = nullptr; module_data->function_symbol_entries = nullptr;
module_data->number_used_function_symbols = 0; module_data->number_used_function_symbols = 0;
} }
module_data->bssAddr = module->getBSSAddr(); module_data->bssAddr = module->getBSSAddr();
module_data->bssSize = module->getBSSSize(); module_data->bssSize = module->getBSSSize();
module_data->sbssAddr = module->getSBSSAddr(); module_data->sbssAddr = module->getSBSSAddr();
module_data->sbssSize = module->getSBSSSize(); module_data->sbssSize = module->getSBSSSize();
module_data->startAddress = module->getStartAddress(); module_data->startAddress = module->getStartAddress();
module_data->endAddress = module->getEndAddress(); module_data->endAddress = module->getEndAddress();
module_data->entrypoint = module->getEntrypoint(); module_data->entrypoint = module->getEntrypoint();
module_data->skipInitFini = module->isSkipInitFini(); module_data->skipInitFini = module->isSkipInitFini();
module_data->initBeforeRelocationDoneHook = module->isInitBeforeRelocationDoneHook(); module_data->initBeforeRelocationDoneHook = module->isInitBeforeRelocationDoneHook();
moduleInformation->number_used_modules++; moduleInformation->number_used_modules++;
@ -120,7 +120,7 @@ std::vector<std::shared_ptr<ModuleData>> ModuleDataPersistence::loadModuleData(m
for (int32_t i = 0; i < module_count; i++) { for (int32_t i = 0; i < module_count; i++) {
// Copy data from struct. // Copy data from struct.
module_information_single_t *module_data = &(moduleInformation->module_data[i]); module_information_single_t *module_data = &(moduleInformation->module_data[i]);
auto moduleData = std::make_shared<ModuleData>(); auto moduleData = std::make_shared<ModuleData>();
moduleData->setBSSLocation(module_data->bssAddr, module_data->bssSize); moduleData->setBSSLocation(module_data->bssAddr, module_data->bssSize);
moduleData->setSBSSLocation(module_data->sbssAddr, module_data->sbssSize); moduleData->setSBSSLocation(module_data->sbssAddr, module_data->sbssSize);
moduleData->setEntrypoint(module_data->entrypoint); moduleData->setEntrypoint(module_data->entrypoint);
@ -130,7 +130,7 @@ std::vector<std::shared_ptr<ModuleData>> ModuleDataPersistence::loadModuleData(m
moduleData->setSkipInitFini(module_data->skipInitFini); moduleData->setSkipInitFini(module_data->skipInitFini);
moduleData->setInitBeforeRelocationDoneHook(module_data->initBeforeRelocationDoneHook); moduleData->setInitBeforeRelocationDoneHook(module_data->initBeforeRelocationDoneHook);
for (auto &export_entrie: module_data->export_entries) { for (auto &export_entrie : module_data->export_entries) {
export_data_t *export_entry = &export_entrie; export_data_t *export_entry = &export_entrie;
if (export_entry->address == 0) { if (export_entry->address == 0) {
continue; continue;
@ -139,7 +139,7 @@ std::vector<std::shared_ptr<ModuleData>> ModuleDataPersistence::loadModuleData(m
moduleData->addExportData(exportData); moduleData->addExportData(exportData);
} }
for (auto &hook_entry: module_data->hook_entries) { for (auto &hook_entry : module_data->hook_entries) {
if (hook_entry.target == 0) { if (hook_entry.target == 0) {
continue; continue;
} }
@ -147,7 +147,7 @@ std::vector<std::shared_ptr<ModuleData>> ModuleDataPersistence::loadModuleData(m
moduleData->addHookData(hookData); moduleData->addHookData(hookData);
} }
for (auto &linking_entry: module_data->linking_entries) { for (auto &linking_entry : module_data->linking_entries) {
if (linking_entry.destination == nullptr) { if (linking_entry.destination == nullptr) {
break; break;
} }
@ -163,14 +163,14 @@ std::vector<std::shared_ptr<ModuleData>> ModuleDataPersistence::loadModuleData(m
continue; continue;
} }
auto rplInfo = std::make_shared<ImportRPLInformation>(importEntry->importName, importEntry->isData); auto rplInfo = std::make_shared<ImportRPLInformation>(importEntry->importName, importEntry->isData);
auto reloc = std::make_shared<RelocationData>(linking_entry.type, linking_entry.offset, linking_entry.addend, linking_entry.destination, functionEntry->functionName, rplInfo); auto reloc = std::make_shared<RelocationData>(linking_entry.type, linking_entry.offset, linking_entry.addend, linking_entry.destination, functionEntry->functionName, rplInfo);
moduleData->addRelocationData(reloc); moduleData->addRelocationData(reloc);
} }
if (module_data->function_symbol_entries != nullptr && module_data->number_used_function_symbols > 0) { if (module_data->function_symbol_entries != nullptr && module_data->number_used_function_symbols > 0) {
for (uint32_t j = 0; j < module_data->number_used_function_symbols; j++) { for (uint32_t j = 0; j < module_data->number_used_function_symbols; j++) {
auto symbol = &module_data->function_symbol_entries[j]; auto symbol = &module_data->function_symbol_entries[j];
auto functionSymbolData = std::make_shared<FunctionSymbolData>(symbol->name, symbol->address, symbol->size); auto functionSymbolData = std::make_shared<FunctionSymbolData>(symbol->name, symbol->address, symbol->size);
moduleData->addFunctionSymbolData(functionSymbolData); moduleData->addFunctionSymbolData(functionSymbolData);
} }

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <wums.h>
#include "ModuleData.h" #include "ModuleData.h"
#include <wums.h>
class ModuleDataPersistence { class ModuleDataPersistence {
public: public:

View File

@ -17,20 +17,20 @@
#pragma once #pragma once
#include <string>
#include <memory>
#include <utility>
#include "ImportRPLInformation.h" #include "ImportRPLInformation.h"
#include <memory>
#include <string>
#include <utility>
class RelocationData { class RelocationData {
public: public:
RelocationData(char type, size_t offset, int32_t addend, void *destination, std::string name, std::shared_ptr<ImportRPLInformation> rplInfo) : rplInfo(std::move(rplInfo)) { RelocationData(char type, size_t offset, int32_t addend, void *destination, std::string name, std::shared_ptr<ImportRPLInformation> rplInfo) : rplInfo(std::move(rplInfo)) {
this->type = type; this->type = type;
this->offset = offset; this->offset = offset;
this->addend = addend; this->addend = addend;
this->destination = destination; this->destination = destination;
this->name = std::move(name); this->name = std::move(name);
} }
~RelocationData() = default; ~RelocationData() = default;

View File

@ -23,18 +23,16 @@
class SectionInfo { class SectionInfo {
public: public:
SectionInfo(std::string name, uint32_t address, uint32_t sectionSize) : SectionInfo(std::string name, uint32_t address, uint32_t sectionSize) : name(std::move(name)),
name(std::move(name)), address(address),
address(address), sectionSize(sectionSize) {
sectionSize(sectionSize) {
} }
SectionInfo() = default; SectionInfo() = default;
SectionInfo(const SectionInfo &o2) : SectionInfo(const SectionInfo &o2) : name(o2.name),
name(o2.name), address(o2.address),
address(o2.address), sectionSize(o2.sectionSize) {
sectionSize(o2.sectionSize) {
} }
SectionInfo &operator=(const SectionInfo &other) = default; SectionInfo &operator=(const SectionInfo &other) = default;

View File

@ -23,17 +23,16 @@
* *
* for WiiXplorer 2010 * for WiiXplorer 2010
***************************************************************************/ ***************************************************************************/
#include <vector>
#include <string>
#include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <string.h>
#include <wchar.h> #include <string>
#include <strings.h> #include <strings.h>
#include <wut_types.h>
#include <stdio.h>
#include <utils/StringTools.h> #include <utils/StringTools.h>
#include <vector>
#include <wchar.h>
#include <wut_types.h>
BOOL StringTools::EndsWith(const std::string &a, const std::string &b) { BOOL StringTools::EndsWith(const std::string &a, const std::string &b) {
@ -85,7 +84,7 @@ const wchar_t *StringTools::wfmt(const char *format, ...) {
static char tmp[512]; static char tmp[512];
static wchar_t strWChar[512]; static wchar_t strWChar[512];
strWChar[0] = 0; strWChar[0] = 0;
tmp[0] = 0; tmp[0] = 0;
if (!format) if (!format)
return (const wchar_t *) strWChar; return (const wchar_t *) strWChar;
@ -98,7 +97,7 @@ const wchar_t *StringTools::wfmt(const char *format, ...) {
if ((vsprintf(tmp, format, va) >= 0)) { if ((vsprintf(tmp, format, va) >= 0)) {
int bt; int bt;
int32_t strlength = strlen(tmp); int32_t strlength = strlen(tmp);
bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512); bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512);
if (bt > 0) { if (bt > 0) {
strWChar[bt] = 0; strWChar[bt] = 0;
@ -112,13 +111,13 @@ const wchar_t *StringTools::wfmt(const char *format, ...) {
int32_t StringTools::strprintf(std::string &str, const char *format, ...) { int32_t StringTools::strprintf(std::string &str, const char *format, ...) {
static char tmp[512]; static char tmp[512];
tmp[0] = 0; tmp[0] = 0;
int32_t result = 0; int32_t result = 0;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if ((vsprintf(tmp, format, va) >= 0)) { if ((vsprintf(tmp, format, va) >= 0)) {
str = tmp; str = tmp;
result = str.size(); result = str.size();
} }
va_end(va); va_end(va);
@ -215,7 +214,7 @@ const char *StringTools::FullpathToFilename(const char *path) {
if (!path) if (!path)
return path; return path;
const char *ptr = path; const char *ptr = path;
const char *Filename = ptr; const char *Filename = ptr;
while (*ptr != '\0') { while (*ptr != '\0') {
@ -244,13 +243,13 @@ void StringTools::RemoveDoubleSlashs(std::string &str) {
// You must free the result if result is non-NULL. // You must free the result if result is non-NULL.
char *StringTools::str_replace(char *orig, char *rep, char *with) { char *StringTools::str_replace(char *orig, char *rep, char *with) {
char *result; // the return string char *result; // the return string
char *ins; // the next insert point char *ins; // the next insert point
char *tmp; // varies char *tmp; // varies
int len_rep; // length of rep (the string to remove) int len_rep; // length of rep (the string to remove)
int len_with; // length of with (the string to replace rep with) int len_with; // length of with (the string to replace rep with)
int len_front; // distance between rep and end of last rep int len_front; // distance between rep and end of last rep
int count; // number of replacements int count; // number of replacements
// sanity checks and initialization // sanity checks and initialization
if (!orig || !rep) if (!orig || !rep)
@ -279,10 +278,10 @@ char *StringTools::str_replace(char *orig, char *rep, char *with) {
// ins points to the next occurrence of rep in orig // ins points to the next occurrence of rep in orig
// orig points to the remainder of orig after "end of rep" // orig points to the remainder of orig after "end of rep"
while (count--) { while (count--) {
ins = strstr(orig, rep); ins = strstr(orig, rep);
len_front = ins - orig; len_front = ins - orig;
tmp = strncpy(tmp, orig, len_front) + len_front; tmp = strncpy(tmp, orig, len_front) + len_front;
tmp = strcpy(tmp, with) + len_with; tmp = strcpy(tmp, with) + len_with;
orig += len_front + len_rep; // move to next "end of rep" orig += len_front + len_rep; // move to next "end of rep"
} }
strcpy(tmp, orig); strcpy(tmp, orig);

View File

@ -26,8 +26,8 @@
#ifndef __STRING_TOOLS_H #ifndef __STRING_TOOLS_H
#define __STRING_TOOLS_H #define __STRING_TOOLS_H
#include <vector>
#include <string> #include <string>
#include <vector>
#include <wut_types.h> #include <wut_types.h>
class StringTools { class StringTools {
@ -62,4 +62,3 @@ public:
}; };
#endif /* __STRING_TOOLS_H */ #endif /* __STRING_TOOLS_H */

View File

@ -1,19 +1,19 @@
#ifdef DEBUG #ifdef DEBUG
#include <stdint.h> #include <stdint.h>
#include <whb/log_udp.h>
#include <whb/log_cafe.h> #include <whb/log_cafe.h>
#include <whb/log_module.h> #include <whb/log_module.h>
#include <whb/log_udp.h>
uint32_t moduleLogInit = false; uint32_t moduleLogInit = false;
uint32_t cafeLogInit = false; uint32_t cafeLogInit = false;
uint32_t udpLogInit = false; uint32_t udpLogInit = false;
#endif // DEBUG #endif // DEBUG
void initLogging() { void initLogging() {
#ifdef DEBUG #ifdef DEBUG
if (!(moduleLogInit = WHBLogModuleInit())) { if (!(moduleLogInit = WHBLogModuleInit())) {
cafeLogInit = WHBLogCafeInit(); cafeLogInit = WHBLogCafeInit();
udpLogInit = WHBLogUdpInit(); udpLogInit = WHBLogUdpInit();
} }
#endif // DEBUG #endif // DEBUG
} }

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <whb/log.h>
#include <string.h> #include <string.h>
#include <whb/log.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -9,26 +9,28 @@ extern "C" {
#ifdef DEBUG #ifdef DEBUG
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) #define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__) #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__)
#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0) #define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0)
#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \ #define DEBUG_FUNCTION_LINE(FMT, ARGS...) \
WHBLogPrintf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ do { \
WHBLogPrintf("[%23s]%30s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
} while (0) } while (0)
#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...)do { \ #define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) \
WHBLogWritef("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ do { \
WHBLogWritef("[%23s]%30s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
} while (0) } while (0)
#else #else
#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0) #define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0)
#define DEBUG_FUNCTION_LINE(FMT, ARGS...) while (0) #define DEBUG_FUNCTION_LINE(FMT, ARGS...) while (0)
#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) while (0) #define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) while (0)
#endif #endif
@ -39,4 +41,3 @@ void deinitLogging();
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,7 +1,7 @@
#include <string.h>
#include <stddef.h>
#include <whb/log.h>
#include "utils/logger.h" #include "utils/logger.h"
#include <stddef.h>
#include <string.h>
#include <whb/log.h>
// https://gist.github.com/ccbrown/9722406 // https://gist.github.com/ccbrown/9722406
void dumpHex(const void *data, size_t size) { void dumpHex(const void *data, size_t size) {

View File

@ -7,28 +7,29 @@
extern "C" { extern "C" {
#endif #endif
#define LIMIT(x, min, max) \ #define LIMIT(x, min, max) \
({ \ ({ \
typeof( x ) _x = x; \ typeof(x) _x = x; \
typeof( min ) _min = min; \ typeof(min) _min = min; \
typeof( max ) _max = max; \ typeof(max) _max = max; \
( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \ (((_x) < (_min)) ? (_min) : ((_x) > (_max)) ? (_max) \
}) : (_x)); \
})
#define DegToRad(a) ( (a) * 0.01745329252f ) #define DegToRad(a) ((a) *0.01745329252f)
#define RadToDeg(a) ( (a) * 57.29577951f ) #define RadToDeg(a) ((a) *57.29577951f)
#define ALIGN4(x) (((x) + 3) & ~3) #define ALIGN4(x) (((x) + 3) & ~3)
#define ALIGN32(x) (((x) + 31) & ~31) #define ALIGN32(x) (((x) + 31) & ~31)
// those work only in powers of 2 // those work only in powers of 2
#define ROUNDDOWN(val, align) ((val) & ~(align-1)) #define ROUNDDOWN(val, align) ((val) & ~(align - 1))
#define ROUNDUP(val, align) ROUNDDOWN(((val) + (align-1)), align) #define ROUNDUP(val, align) ROUNDDOWN(((val) + (align - 1)), align)
#define le16(i) ((((uint16_t) ((i) & 0xFF)) << 8) | ((uint16_t) (((i) & 0xFF00) >> 8))) #define le16(i) ((((uint16_t) ((i) &0xFF)) << 8) | ((uint16_t) (((i) &0xFF00) >> 8)))
#define le32(i) ((((uint32_t)le16((i) & 0xFFFF)) << 16) | ((uint32_t)le16(((i) & 0xFFFF0000) >> 16))) #define le32(i) ((((uint32_t) le16((i) &0xFFFF)) << 16) | ((uint32_t) le16(((i) &0xFFFF0000) >> 16)))
#define le64(i) ((((uint64_t)le32((i) & 0xFFFFFFFFLL)) << 32) | ((uint64_t)le32(((i) & 0xFFFFFFFF00000000LL) >> 32))) #define le64(i) ((((uint64_t) le32((i) &0xFFFFFFFFLL)) << 32) | ((uint64_t) le32(((i) &0xFFFFFFFF00000000LL) >> 32)))
//Needs to have log_init() called beforehand. //Needs to have log_init() called beforehand.
void dumpHex(const void *data, size_t size); void dumpHex(const void *data, size_t size);