diff --git a/source/module/ModuleDataFactory.cpp b/source/module/ModuleDataFactory.cpp index 22c892b..e0d063f 100644 --- a/source/module/ModuleDataFactory.cpp +++ b/source/module/ModuleDataFactory.cpp @@ -17,6 +17,7 @@ #include "ModuleDataFactory.h" #include "ElfUtils.h" +#include "utils/FileUtils.h" #include "utils/utils.h" #include #include @@ -31,29 +32,18 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p elfio reader; std::shared_ptr moduleData = std::make_shared(); - FILE *f = fopen(path.c_str(), "rb"); - fseek(f, 0, SEEK_END); - auto fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - auto *buffer = static_cast(memalign(0x40, ROUNDUP(fsize + 1, 0x40))); - if (!buffer) { - fclose(f); - DEBUG_FUNCTION_LINE("Failed to allocate buffer"); - } - if ((long) fread(buffer, fsize, 1, f) != fsize) { - DEBUG_FUNCTION_LINE("Failed to load data into buffer"); - free(buffer); - fclose(f); + uint8_t *buffer = nullptr; + uint32_t fsize = 0; + if (LoadFileToMem(path.c_str(), &buffer, &fsize) < 0) { + DEBUG_FUNCTION_LINE("Failed to load file"); return {}; } - fclose(f); // Load ELF data - if (!reader.load(buffer, fsize)) { + if (!reader.load(reinterpret_cast(buffer), fsize)) { DEBUG_FUNCTION_LINE("Can't find or process %s", path.c_str()); free(buffer); - return std::nullopt; + return {}; } uint32_t sec_num = reader.sections.size(); diff --git a/source/utils/FileUtils.cpp b/source/utils/FileUtils.cpp new file mode 100644 index 0000000..aa9b2fa --- /dev/null +++ b/source/utils/FileUtils.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/source/utils/FileUtils.h b/source/utils/FileUtils.h new file mode 100644 index 0000000..e9b0bc7 --- /dev/null +++ b/source/utils/FileUtils.h @@ -0,0 +1,3 @@ +#pragma once + +int32_t LoadFileToMem(const char *filepath, uint8_t **inbuffer, uint32_t *size); \ No newline at end of file