bool readSections(BigEndianView &in, Header &header, std::vector<Section> §ions) { sections.resize(header.shnum); for (auto i = 0u; i < sections.size(); ++i) { auto §ion = sections[i]; // Read section header in.seek(header.shoff + header.shentsize * i); readSectionHeader(in, section.header); if ((section.header.type == SHT_NOBITS) || !section.header.size) { continue; } // Read section data if (section.header.flags & SHF_DEFLATED) { auto stream = z_stream {}; auto ret = Z_OK; // Read the original size in.seek(section.header.offset); section.data.resize(in.read<uint32_t>()); // Inflate memset(&stream, 0, sizeof(stream)); stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; ret = inflateInit(&stream); if (ret != Z_OK) { gLog->error("Couldn't decompress .rpx section because inflateInit returned {}", ret); section.data.clear(); } else { stream.avail_in = section.header.size; stream.next_in = in.readRaw<Bytef>(section.header.size); stream.avail_out = static_cast<uInt>(section.data.size()); stream.next_out = reinterpret_cast<Bytef*>(section.data.data()); ret = inflate(&stream, Z_FINISH); if (ret != Z_OK && ret != Z_STREAM_END) { gLog->error("Couldn't decompress .rpx section because inflate returned {}", ret); section.data.clear(); } inflateEnd(&stream); } } else { section.data.resize(section.header.size); in.seek(section.header.offset); in.read(section.data.data(), section.header.size); } } return true; }
bool readSectionData(BigEndianView &in, const SectionHeader& header, std::vector<uint8_t> &data) { if (header.type == SHT_NOBITS || header.size == 0) { data.clear(); return true; } if (header.flags & SHF_DEFLATED) { auto stream = z_stream{}; auto ret = Z_OK; // Read the original size in.seek(header.offset); data.resize(in.read<uint32_t>()); // Inflate memset(&stream, 0, sizeof(stream)); stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; ret = inflateInit(&stream); if (ret != Z_OK) { gLog->error("Couldn't decompress .rpx section because inflateInit returned {}", ret); data.clear(); } else { stream.avail_in = header.size; stream.next_in = const_cast<Bytef*>(in.readRaw<Bytef>(header.size)); stream.avail_out = static_cast<uInt>(data.size()); stream.next_out = reinterpret_cast<Bytef*>(data.data()); ret = inflate(&stream, Z_FINISH); if (ret != Z_OK && ret != Z_STREAM_END) { gLog->error("Couldn't decompress .rpx section because inflate returned {}", ret); data.clear(); } inflateEnd(&stream); } } else { data.resize(header.size); in.seek(header.offset); in.read(data.data(), header.size); } return data.size() > 0; }
// Get symbol at index static elf::Symbol getSymbol(BigEndianView &symSecView, uint32_t index) { elf::Symbol sym; symSecView.seek(index * sizeof(elf::Symbol)); elf::readSymbol(symSecView, sym); return sym; }
bool readSectionHeaders(BigEndianView &in, Header &header, std::vector<XSection>& sections) { sections.resize(header.shnum); for (auto i = 0u; i < sections.size(); ++i) { auto §ionHeader = sections[i].header; in.seek(header.shoff + header.shentsize * i); if (!readSectionHeader(in, sectionHeader)) { return false; } } return true; }