From d6478d831e69dd6b4eeaf12d7c65be9258dba4bd Mon Sep 17 00:00:00 2001 From: James Benton Date: Thu, 24 May 2018 23:32:35 +0100 Subject: [PATCH] elf2rpl: Add support for section deflation. --- tools/elf2rpl/main.cpp | 68 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/tools/elf2rpl/main.cpp b/tools/elf2rpl/main.cpp index 273cfd7..59b70cf 100644 --- a/tools/elf2rpl/main.cpp +++ b/tools/elf2rpl/main.cpp @@ -10,9 +10,10 @@ #include #include -constexpr auto CodeBaseAddress = 0x02000000; -constexpr auto DataBaseAddress = 0x10000000; -constexpr auto LoadBaseAddress = 0xC0000000; +constexpr auto DeflateMinSectionSize = 0x18u; +constexpr auto CodeBaseAddress = 0x02000000u; +constexpr auto DataBaseAddress = 0x10000000u; +constexpr auto LoadBaseAddress = 0xC0000000u; struct ElfFile { @@ -548,7 +549,6 @@ fixRelocations(ElfFile &file) } } - section->data.insert(section->data.end(), reinterpret_cast(newRelocations.data()), reinterpret_cast(newRelocations.data() + newRelocations.size())); @@ -721,6 +721,61 @@ fixLoaderVirtualAddresses(ElfFile &file) return true; } +static bool +deflateSections(ElfFile &file) +{ + std::vector chunk; + chunk.resize(16 * 1024); + + for (auto §ion : file.sections) { + if (section->data.size() < DeflateMinSectionSize || + section->header.type == elf::SHT_RPL_CRCS || + section->header.type == elf::SHT_RPL_FILEINFO) { + continue; + } + + // Allocate space for the 4 bytes inflated size + std::vector deflated; + deflated.resize(4); + + // Deflate section data + auto stream = z_stream { }; + memset(&stream, 0, sizeof(stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + deflateInit(&stream, 6); + + stream.avail_in = section->data.size(); + stream.next_in = reinterpret_cast(section->data.data()); + + do { + stream.avail_out = static_cast(chunk.size()); + stream.next_out = reinterpret_cast(chunk.data()); + + auto ret = deflate(&stream, Z_FINISH); + if (ret == Z_STREAM_ERROR) { + deflateEnd(&stream); + return false; + } + + deflated.insert(deflated.end(), + chunk.data(), + reinterpret_cast(stream.next_out)); + } while (stream.avail_out == 0); + deflateEnd(&stream); + + // Set the inflated size at start of section + *reinterpret_cast *>(&deflated[0]) = + static_cast(section->data.size()); + + // Update the section data + section->data = std::move(deflated); + section->header.flags |= elf::SHF_DEFLATED; + } + + return true; +} /** * Calculate section file offsets. @@ -943,6 +998,11 @@ int main(int argc, const char **argv) return -1; } + if (!deflateSections(elf)) { + fmt::print("ERROR: deflateSections failed"); + return -1; + } + if (!calculateSectionOffsets(elf)) { fmt::print("ERROR: calculateSectionOffsets failed"); return -1;