mirror of
https://github.com/wiiu-env/WUMSLoader.git
synced 2024-11-27 10:04:16 +01:00
Improve error handling by using std::nothrow everywhere
This commit is contained in:
parent
99791f5edf
commit
ef91f1ef11
@ -244,11 +244,15 @@ class section_impl : public section
|
||||
if ( ( 0 != size ) && ( 0 != data ) ) {
|
||||
stream.seekg( (*convertor)( header.sh_offset ) );
|
||||
if (get_flags() & 0x08000000){
|
||||
uint32_t uncompressed_size = size;
|
||||
stream.read( (char *) &uncompressed_size, 4);
|
||||
uint32_t decompressed_size = size;
|
||||
stream.read( (char *) &decompressed_size, 4);
|
||||
stream.read( data, size - 4);
|
||||
|
||||
char* uncompressedData = new char[uncompressed_size + 1];
|
||||
char* decompressedData = new (std::nothrow) char[decompressed_size + 1];
|
||||
if(!decompressedData) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to allocated memory for decompressing the section");
|
||||
OSFatal("Failed to allocated memory for decompressing the section");
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
z_stream s;
|
||||
@ -265,8 +269,8 @@ class section_impl : public section
|
||||
s.avail_in = size - 4;
|
||||
s.next_in = (Bytef *)data;
|
||||
|
||||
s.avail_out = uncompressed_size;
|
||||
s.next_out = (Bytef *)&uncompressedData[0];
|
||||
s.avail_out = decompressed_size;
|
||||
s.next_out = (Bytef *)&decompressedData[0];
|
||||
|
||||
ret = inflate(&s, Z_FINISH);
|
||||
if (ret != Z_OK && ret != Z_STREAM_END){
|
||||
@ -276,9 +280,9 @@ class section_impl : public section
|
||||
inflateEnd(&s);
|
||||
|
||||
delete [] data;
|
||||
data = uncompressedData;
|
||||
data_size = uncompressed_size;
|
||||
set_size(uncompressed_size);
|
||||
data = decompressedData;
|
||||
data_size = decompressed_size;
|
||||
set_size(decompressed_size);
|
||||
data[data_size] = 0; // Ensure data is ended with 0 to avoid oob read
|
||||
|
||||
}else{
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "utils/ElfUtils.h"
|
||||
#include "utils/OnLeavingScope.h"
|
||||
#include "utils/logger.h"
|
||||
#include "utils/utils.h"
|
||||
#include <coreinit/cache.h>
|
||||
#include <coreinit/memdefaultheap.h>
|
||||
#include <map>
|
||||
@ -30,7 +31,7 @@ using namespace ELFIO;
|
||||
|
||||
std::optional<std::shared_ptr<ModuleData>> ModuleDataFactory::load(const std::string &path) {
|
||||
elfio reader;
|
||||
auto moduleData = std::make_shared<ModuleData>();
|
||||
auto moduleData = make_shared_nothrow<ModuleData>();
|
||||
if (!moduleData) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to alloc module data");
|
||||
return {};
|
||||
@ -52,7 +53,7 @@ std::optional<std::shared_ptr<ModuleData>> ModuleDataFactory::load(const std::st
|
||||
}
|
||||
uint32_t sec_num = reader.sections.size();
|
||||
|
||||
auto destinations = std::make_unique<uint8_t *[]>(sec_num);
|
||||
auto destinations = make_unique_nothrow<uint8_t *[]>(sec_num);
|
||||
if (!destinations) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed alloc memory for destinations array");
|
||||
return {};
|
||||
@ -83,7 +84,7 @@ std::optional<std::shared_ptr<ModuleData>> ModuleDataFactory::load(const std::st
|
||||
}
|
||||
}
|
||||
|
||||
auto data = std::make_unique<uint8_t[]>(text_size + data_size);
|
||||
auto data = make_unique_nothrow<uint8_t[]>(text_size + data_size);
|
||||
if (!data) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to alloc memory for the .text section (%d bytes)", text_size);
|
||||
return {};
|
||||
@ -146,7 +147,11 @@ std::optional<std::shared_ptr<ModuleData>> ModuleDataFactory::load(const std::st
|
||||
moduleData->setSBSSLocation(destination, sectionSize);
|
||||
memset(reinterpret_cast<void *>(destination), 0, sectionSize);
|
||||
}
|
||||
auto sectionInfo = std::make_shared<SectionInfo>(psec->get_name(), destination, sectionSize);
|
||||
auto sectionInfo = make_shared_nothrow<SectionInfo>(psec->get_name(), destination, sectionSize);
|
||||
if (!sectionInfo) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to allocate memory for section info");
|
||||
return {};
|
||||
}
|
||||
moduleData->addSectionInfo(sectionInfo);
|
||||
DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), destination, sectionSize);
|
||||
|
||||
@ -175,9 +180,10 @@ std::optional<std::shared_ptr<ModuleData>> ModuleDataFactory::load(const std::st
|
||||
for (size_t j = 0; j < entries_count; j++) {
|
||||
wums_entry_t *exp = &entries[j];
|
||||
DEBUG_FUNCTION_LINE("Saving export of type %08X, name %s, target: %08X", exp->type, exp->name, exp->address);
|
||||
auto exportData = std::make_unique<ExportData>(exp->type, exp->name, exp->address);
|
||||
auto exportData = make_unique_nothrow<ExportData>(exp->type, exp->name, exp->address);
|
||||
if (!exportData) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to alloc ExportData");
|
||||
return {};
|
||||
}
|
||||
moduleData->addExportData(std::move(exportData));
|
||||
}
|
||||
@ -192,9 +198,10 @@ std::optional<std::shared_ptr<ModuleData>> ModuleDataFactory::load(const std::st
|
||||
for (size_t j = 0; j < entries_count; j++) {
|
||||
wums_hook_t *hook = &hooks[j];
|
||||
DEBUG_FUNCTION_LINE("Saving hook of type %08X, target: %08X", hook->type, hook->target);
|
||||
auto hookData = std::make_unique<HookData>(hook->type, hook->target);
|
||||
auto hookData = make_unique_nothrow<HookData>(hook->type, hook->target);
|
||||
if (!hookData) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to alloc HookData");
|
||||
return {};
|
||||
}
|
||||
moduleData->addHookData(std::move(hookData));
|
||||
}
|
||||
@ -272,9 +279,10 @@ std::optional<std::shared_ptr<ModuleData>> ModuleDataFactory::load(const std::st
|
||||
continue;
|
||||
}
|
||||
auto finalAddress = offsetVal + sectionOpt.value()->getAddress();
|
||||
auto functionSymbolData = std::make_shared<FunctionSymbolData>(name, (void *) finalAddress, (uint32_t) size);
|
||||
auto functionSymbolData = make_shared_nothrow<FunctionSymbolData>(name, (void *) finalAddress, (uint32_t) size);
|
||||
if (!functionSymbolData) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to alloc FunctionSymbolData");
|
||||
return std::nullopt;
|
||||
} else {
|
||||
moduleData->addFunctionSymbolData(std::move(functionSymbolData));
|
||||
}
|
||||
@ -293,7 +301,7 @@ std::optional<std::shared_ptr<ModuleData>> ModuleDataFactory::load(const std::st
|
||||
|
||||
if (totalSize > text_size + data_size) {
|
||||
DEBUG_FUNCTION_LINE_ERR("We didn't allocate enough memory!!");
|
||||
OSFatal("We didn't allocate enough memory!!");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
moduleData->setDataPtr(std::move(data), totalSize);
|
||||
@ -307,7 +315,7 @@ std::optional<std::shared_ptr<ModuleData>> ModuleDataFactory::load(const std::st
|
||||
return moduleData;
|
||||
}
|
||||
|
||||
void ModuleDataFactory::getImportRelocationData(std::shared_ptr<ModuleData> &moduleData, ELFIO::elfio &reader, uint8_t **destinations) {
|
||||
bool ModuleDataFactory::getImportRelocationData(std::shared_ptr<ModuleData> &moduleData, ELFIO::elfio &reader, uint8_t **destinations) {
|
||||
std::map<uint32_t, std::shared_ptr<ImportRPLInformation>> infoMap;
|
||||
|
||||
uint32_t sec_num = reader.sections.size();
|
||||
@ -315,7 +323,12 @@ void ModuleDataFactory::getImportRelocationData(std::shared_ptr<ModuleData> &mod
|
||||
for (uint32_t i = 0; i < sec_num; ++i) {
|
||||
auto *psec = reader.sections[i];
|
||||
if (psec->get_type() == 0x80000002) {
|
||||
infoMap[i] = std::make_shared<ImportRPLInformation>(psec->get_name());
|
||||
auto info = make_shared_nothrow<ImportRPLInformation>(psec->get_name());
|
||||
if (!info) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed too allocate ImportRPLInformation");
|
||||
return false;
|
||||
}
|
||||
infoMap[i] = std::move(info);
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,23 +361,23 @@ void ModuleDataFactory::getImportRelocationData(std::shared_ptr<ModuleData> &mod
|
||||
OSFatal("Relocation is referencing a unknown section.");
|
||||
}
|
||||
|
||||
auto relocationData = std::make_unique<RelocationData>(type,
|
||||
offset - 0x02000000,
|
||||
addend,
|
||||
(void *) (destinations[section_index] + 0x02000000),
|
||||
sym_name,
|
||||
infoMap[sym_section_index]);
|
||||
auto relocationData = make_unique_nothrow<RelocationData>(type,
|
||||
offset - 0x02000000,
|
||||
addend,
|
||||
(void *) (destinations[section_index] + 0x02000000),
|
||||
sym_name,
|
||||
infoMap[sym_section_index]);
|
||||
|
||||
if (!relocationData) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to alloc relocation data");
|
||||
OSFatal("Failed to alloc relocation data");
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
|
||||
moduleData->addRelocationData(std::move(relocationData));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModuleDataFactory::linkSection(elfio &reader, uint32_t section_index, uint32_t destination, uint32_t base_text, uint32_t base_data, relocation_trampoline_entry_t *trampoline_data,
|
||||
@ -386,8 +399,7 @@ bool ModuleDataFactory::linkSection(elfio &reader, uint32_t section_index, uint3
|
||||
|
||||
if (!rel.get_entry(j, offset, sym_value, sym_name, type, addend, sym_section_index)) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to get relocation");
|
||||
OSFatal("Failed to get relocation");
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto adjusted_sym_value = (uint32_t) sym_value;
|
||||
|
@ -37,5 +37,5 @@ public:
|
||||
relocation_trampoline_entry_t *trampoline_data,
|
||||
uint32_t trampoline_data_length);
|
||||
|
||||
static void getImportRelocationData(std::shared_ptr<ModuleData> &moduleData, ELFIO::elfio &reader, uint8_t **destinations);
|
||||
static bool getImportRelocationData(std::shared_ptr<ModuleData> &moduleData, ELFIO::elfio &reader, uint8_t **destinations);
|
||||
};
|
||||
|
@ -1,9 +1,10 @@
|
||||
#include "ModuleDataPersistence.h"
|
||||
#include "globals.h"
|
||||
#include "utils/utils.h"
|
||||
#include <coreinit/cache.h>
|
||||
|
||||
bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformation, const std::vector<std::shared_ptr<ModuleData>> &moduleList) {
|
||||
auto module_data_list = std::make_unique<module_information_single_t[]>(moduleList.size());
|
||||
auto module_data_list = make_unique_nothrow<module_information_single_t[]>(moduleList.size());
|
||||
if (!module_data_list) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to alloc memory to persist module data");
|
||||
return false;
|
||||
@ -73,7 +74,7 @@ bool ModuleDataPersistence::saveModuleData(module_information_single_t &module_d
|
||||
|
||||
bool ModuleDataPersistence::saveFunctionSymbolDataForModule(module_information_single_t &module_data, const std::shared_ptr<ModuleData> &module) {
|
||||
uint32_t entryCount = module->getFunctionSymbolDataList().size();
|
||||
auto function_symbol_data = std::make_unique<module_function_symbol_data_t[]>(entryCount);
|
||||
auto function_symbol_data = make_unique_nothrow<module_function_symbol_data_t[]>(entryCount);
|
||||
if (!function_symbol_data) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to allocate memory for the function symbol data.");
|
||||
return false;
|
||||
@ -98,7 +99,7 @@ bool ModuleDataPersistence::saveFunctionSymbolDataForModule(module_information_s
|
||||
}
|
||||
|
||||
bool ModuleDataPersistence::saveExportDataForModule(module_information_single_t &module_data, const std::shared_ptr<ModuleData> &module) {
|
||||
auto export_data = std::make_unique<export_data_t[]>(module->getExportDataList().size());
|
||||
auto export_data = make_unique_nothrow<export_data_t[]>(module->getExportDataList().size());
|
||||
if (!export_data) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to allocate memory for the export data.");
|
||||
return false;
|
||||
@ -124,7 +125,7 @@ bool ModuleDataPersistence::saveExportDataForModule(module_information_single_t
|
||||
}
|
||||
|
||||
bool ModuleDataPersistence::saveHookDataForModule(module_information_single_t &module_data, const std::shared_ptr<ModuleData> &module) {
|
||||
auto hook_data = std::make_unique<hook_data_t[]>(module->getHookDataList().size());
|
||||
auto hook_data = make_unique_nothrow<hook_data_t[]>(module->getHookDataList().size());
|
||||
if (!hook_data) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to allocate memory for the hook data.");
|
||||
return false;
|
||||
@ -149,7 +150,7 @@ bool ModuleDataPersistence::saveHookDataForModule(module_information_single_t &m
|
||||
}
|
||||
|
||||
bool ModuleDataPersistence::saveRelocationDataForModule(module_information_single_t &module_data, const std::shared_ptr<ModuleData> &module) {
|
||||
auto relocation_data = std::make_unique<dyn_linking_relocation_entry_t[]>(module->getRelocationDataList().size());
|
||||
auto relocation_data = make_unique_nothrow<dyn_linking_relocation_entry_t[]>(module->getRelocationDataList().size());
|
||||
if (!relocation_data) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to allocate memory for the relocation data.");
|
||||
return false;
|
||||
@ -164,7 +165,7 @@ bool ModuleDataPersistence::saveRelocationDataForModule(module_information_singl
|
||||
uint32_t rplInfoTotalCount = rplInfoCountSet.size();
|
||||
rplInfoCountSet.clear();
|
||||
|
||||
auto rpl_data = std::make_unique<dyn_linking_import_t[]>(rplInfoTotalCount);
|
||||
auto rpl_data = make_unique_nothrow<dyn_linking_import_t[]>(rplInfoTotalCount);
|
||||
if (!rpl_data) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to allocate memory for the RPLInfos.");
|
||||
return false;
|
||||
|
@ -25,6 +25,9 @@
|
||||
***************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "logger.h"
|
||||
#include "utils.h"
|
||||
#include <coreinit/debug.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -34,7 +37,12 @@ template<typename... Args>
|
||||
std::string string_format(const std::string &format, Args... args) {
|
||||
int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0'
|
||||
auto size = static_cast<size_t>(size_s);
|
||||
auto buf = std::make_unique<char[]>(size);
|
||||
auto buf = make_unique_nothrow<char[]>(size);
|
||||
if (!buf) {
|
||||
DEBUG_FUNCTION_LINE_ERR("string_format failed, not enough memory");
|
||||
OSFatal("string_format failed, not enough memory");
|
||||
return std::string("");
|
||||
}
|
||||
std::snprintf(buf.get(), size, format.c_str(), args...);
|
||||
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
||||
}
|
||||
|
17
wumsloader/src/utils/utils.h
Normal file
17
wumsloader/src/utils/utils.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
|
||||
template<class T, class... Args>
|
||||
std::unique_ptr<T> make_unique_nothrow(Args &&...args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
|
||||
return std::unique_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline typename std::_MakeUniq<T>::__array make_unique_nothrow(size_t num) noexcept {
|
||||
return std::unique_ptr<T>(new (std::nothrow) std::remove_extent_t<T>[num]());
|
||||
}
|
||||
|
||||
template<class T, class... Args>
|
||||
std::shared_ptr<T> make_shared_nothrow(Args &&...args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
|
||||
return std::shared_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
|
||||
}
|
Loading…
Reference in New Issue
Block a user