Read the payload.rpx with a properly aligned buffer, fix some missing free calls

This commit is contained in:
Maschell 2022-02-13 14:26:48 +01:00
parent 446dacdaac
commit 2291856834
3 changed files with 83 additions and 2 deletions

View File

@ -16,6 +16,7 @@
****************************************************************************/ ****************************************************************************/
#include "ModuleDataFactory.h" #include "ModuleDataFactory.h"
#include "../utils/FileUtils.h"
#include "ElfUtils.h" #include "ElfUtils.h"
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include <map> #include <map>
@ -29,10 +30,18 @@ ModuleDataFactory::load(const std::string &path, uint32_t destination_address_en
elfio reader; elfio reader;
std::shared_ptr<ModuleData> moduleData = std::make_shared<ModuleData>(); std::shared_ptr<ModuleData> moduleData = std::make_shared<ModuleData>();
uint8_t *buffer = nullptr;
uint32_t fsize = 0;
if (LoadFileToMem(path.c_str(), &buffer, &fsize) < 0) {
DEBUG_FUNCTION_LINE("Failed to load file");
return {};
}
// Load ELF data // Load ELF data
if (!reader.load(path)) { if (!reader.load(reinterpret_cast<char *>(buffer), fsize)) {
DEBUG_FUNCTION_LINE("Can't find or process %s", path.c_str()); DEBUG_FUNCTION_LINE("Can't find or process %s", path.c_str());
return std::nullopt; free(buffer);
return {};
} }
uint32_t sec_num = reader.sections.size(); uint32_t sec_num = reader.sections.size();
@ -52,6 +61,8 @@ ModuleDataFactory::load(const std::string &path, uint32_t destination_address_en
if (sizeOfModule > maximum_size) { if (sizeOfModule > maximum_size) {
DEBUG_FUNCTION_LINE("Module is too big."); DEBUG_FUNCTION_LINE("Module is too big.");
free(destinations);
free(buffer);
return {}; return {};
} }
@ -78,6 +89,8 @@ ModuleDataFactory::load(const std::string &path, uint32_t destination_address_en
totalSize += sectionSize; totalSize += sectionSize;
if (totalSize > maximum_size) { if (totalSize > maximum_size) {
DEBUG_FUNCTION_LINE("Couldn't load setup module because it's too big."); DEBUG_FUNCTION_LINE("Couldn't load setup module because it's too big.");
free(destinations);
free(buffer);
return {}; return {};
} }
@ -100,6 +113,7 @@ ModuleDataFactory::load(const std::string &path, uint32_t destination_address_en
} else { } else {
DEBUG_FUNCTION_LINE("Unhandled case"); DEBUG_FUNCTION_LINE("Unhandled case");
free(destinations); free(destinations);
free(buffer);
return std::nullopt; return std::nullopt;
} }
@ -138,6 +152,7 @@ ModuleDataFactory::load(const std::string &path, uint32_t destination_address_en
if (!linkSection(reader, psec->get_index(), (uint32_t) destinations[psec->get_index()], offset_text, offset_data, trampolin_data, trampolin_data_length)) { if (!linkSection(reader, psec->get_index(), (uint32_t) destinations[psec->get_index()], offset_text, offset_data, trampolin_data, trampolin_data_length)) {
DEBUG_FUNCTION_LINE("elfLink failed"); DEBUG_FUNCTION_LINE("elfLink failed");
free(destinations); free(destinations);
free(buffer);
return std::nullopt; return std::nullopt;
} }
} }
@ -152,6 +167,7 @@ ModuleDataFactory::load(const std::string &path, uint32_t destination_address_en
ICInvalidateRange((void *) baseOffset, totalSize); ICInvalidateRange((void *) baseOffset, totalSize);
free(destinations); free(destinations);
free(buffer);
moduleData->setStartAddress(startAddress); moduleData->setStartAddress(startAddress);
moduleData->setEndAddress(endAddress); moduleData->setEndAddress(endAddress);

View File

@ -0,0 +1,62 @@
#include <fcntl.h>
#include <malloc.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define ROUNDDOWN(val, align) ((val) & ~(align - 1))
#define ROUNDUP(val, align) ROUNDDOWN(((val) + (align - 1)), align)
int32_t LoadFileToMem(const char *filepath, uint8_t **inbuffer, uint32_t *size) {
//! always initialze input
*inbuffer = NULL;
if (size) {
*size = 0;
}
int32_t iFd = open(filepath, O_RDONLY);
if (iFd < 0) {
return -1;
}
uint32_t filesize = lseek(iFd, 0, SEEK_END);
lseek(iFd, 0, SEEK_SET);
auto *buffer = (uint8_t *) memalign(0x40, ROUNDUP(filesize, 0x40));
if (buffer == nullptr) {
close(iFd);
return -2;
}
uint32_t blocksize = 0x20000;
uint32_t done = 0;
int32_t readBytes = 0;
while (done < filesize) {
if (done + blocksize > filesize) {
blocksize = filesize - done;
}
readBytes = read(iFd, buffer + done, blocksize);
if (readBytes <= 0)
break;
done += readBytes;
}
::close(iFd);
if (done != filesize) {
free(buffer);
buffer = nullptr;
return -3;
}
*inbuffer = buffer;
//! sign is optional input
if (size) {
*size = filesize;
}
return filesize;
}

3
source/utils/FileUtils.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
int32_t LoadFileToMem(const char *filepath, uint8_t **inbuffer, uint32_t *size);