Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use mmap buffer instead of regular buffer for BinFile::openExisting #6

Merged
merged 2 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 73 additions & 3 deletions src/binfile_utils.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <system_error>
#include <string>
#include <memory.h>
Expand All @@ -8,6 +12,65 @@

namespace BinFileUtils {

BinFile::BinFile(std::string fileName, std::string _type, uint32_t maxVersion) {

is_fd = true;
struct stat sb;

fd = open(fileName.c_str(), O_RDONLY);
if (fd == -1)
throw std::system_error(errno, std::generic_category(), "open");


if (fstat(fd, &sb) == -1) /* To obtain file size */
throw std::system_error(errno, std::generic_category(), "fstat");

size = sb.st_size;

addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (addr == MAP_FAILED) {
close(fd);
throw std::system_error(errno, std::generic_category(), "mmap failed");
}
madvise(addr, size, MADV_SEQUENTIAL);

type.assign((const char *)addr, 4);
pos = 4;

if (type != _type) {
munmap(addr, size);
close(fd);
throw new std::invalid_argument("Invalid file type. It should be " + _type + " and it is " + type + " filename: " + fileName);
}

version = readU32LE();
if (version > maxVersion) {
munmap(addr, size);
close(fd);
throw new std::invalid_argument("Invalid version. It should be <=" + std::to_string(maxVersion) + " and it is " + std::to_string(version));
}

u_int32_t nSections = readU32LE();


for (u_int32_t i=0; i<nSections; i++) {
u_int32_t sType=readU32LE();
u_int64_t sSize=readU64LE();

if (sections.find(sType) == sections.end()) {
sections.insert(std::make_pair(sType, std::vector<Section>()));
}

sections[sType].push_back(Section( (void *)((u_int64_t)addr + pos), sSize));

pos += sSize;
}

pos = 0;
readingSection = NULL;
}


BinFile::BinFile(const void *fileData, size_t fileSize, std::string _type, uint32_t maxVersion) {

size = fileSize;
Expand Down Expand Up @@ -49,7 +112,12 @@ BinFile::BinFile(const void *fileData, size_t fileSize, std::string _type, uint3
}

BinFile::~BinFile() {
free(addr);
if (is_fd) {
munmap(addr, size);
close(fd);
} else {
free(addr);
}
}

void BinFile::startReadSection(u_int32_t sectionId, u_int32_t sectionPos) {
Expand Down Expand Up @@ -126,9 +194,11 @@ void *BinFile::read(u_int64_t len) {

std::unique_ptr<BinFile> openExisting(std::string filename, std::string type, uint32_t maxVersion) {

FileLoader fileLoader(filename);
// FileLoader fileLoader(filename);
//
// return std::unique_ptr<BinFile>(new BinFile(fileLoader.dataBuffer(), fileLoader.dataSize(), type, maxVersion));

return std::unique_ptr<BinFile>(new BinFile(fileLoader.dataBuffer(), fileLoader.dataSize(), type, maxVersion));
return std::unique_ptr<BinFile>(new BinFile(filename, type, maxVersion));
}

} // Namespace
Expand Down
4 changes: 4 additions & 0 deletions src/binfile_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ namespace BinFileUtils {

class BinFile {

bool is_fd;
int fd;

void *addr;
u_int64_t size;
u_int64_t pos;
Expand All @@ -33,6 +36,7 @@ namespace BinFileUtils {
public:

BinFile(const void *fileData, size_t fileSize, std::string _type, uint32_t maxVersion);
BinFile(std::string fileName, std::string _type, uint32_t maxVersion);
~BinFile();

void *getSetcionData(u_int32_t sectionId, u_int32_t sectionPos = 0);
Expand Down