From 75e87a58da1ca56bb595428cff6d703891cd47bd Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Fri, 9 Jun 2023 18:20:06 +0200 Subject: [PATCH] src: rework mem_clear() --- src/compress/compress.cpp | 2 +- src/compress/compress_lzma.cpp | 2 +- src/compress/compress_zlib.cpp | 3 +- src/compress/compress_zstd.cpp | 2 +- src/conf.h | 64 ++++++++++++++++++---------------- src/lefile.cpp | 6 ++-- src/options.cpp | 2 +- src/p_exe.cpp | 4 +-- src/p_wcle.cpp | 5 +-- src/packer.cpp | 4 +-- src/pefile.cpp | 2 +- src/ui.cpp | 2 +- src/util/membuffer.h | 2 +- src/util/util.h | 6 ---- src/work.cpp | 4 +-- 15 files changed, 54 insertions(+), 56 deletions(-) diff --git a/src/compress/compress.cpp b/src/compress/compress.cpp index d190cff7..2badaccf 100644 --- a/src/compress/compress.cpp +++ b/src/compress/compress.cpp @@ -83,7 +83,7 @@ int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned if (!cresult) cresult = &cresult_buffer; - memset(cresult, 0, sizeof(*cresult)); + cresult->reset(); #if 1 // debugging aid cresult->debug.method = method; diff --git a/src/compress/compress_lzma.cpp b/src/compress/compress_lzma.cpp index 11d84b44..791c4586 100644 --- a/src/compress/compress_lzma.cpp +++ b/src/compress/compress_lzma.cpp @@ -433,7 +433,7 @@ int upx_lzma_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, un COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768) CLzmaDecoderState s; - memset(&s, 0, sizeof(s)); + mem_clear(&s); SizeT src_out = 0, dst_out = 0; int r = UPX_E_ERROR; int rh; diff --git a/src/compress/compress_zlib.cpp b/src/compress/compress_zlib.cpp index 8b0b3e5f..d90bc2ea 100644 --- a/src/compress/compress_zlib.cpp +++ b/src/compress/compress_zlib.cpp @@ -31,8 +31,7 @@ #include void zlib_compress_config_t::reset() noexcept { - mem_clear(this, sizeof(*this)); - + mem_clear(this); mem_level.reset(); window_bits.reset(); strategy.reset(); diff --git a/src/compress/compress_zstd.cpp b/src/compress/compress_zstd.cpp index d431f86a..c08c17e9 100644 --- a/src/compress/compress_zstd.cpp +++ b/src/compress/compress_zstd.cpp @@ -26,7 +26,7 @@ #include "../conf.h" -void zstd_compress_config_t::reset() noexcept { mem_clear(this, sizeof(*this)); } +void zstd_compress_config_t::reset() noexcept { mem_clear(this); } #if WITH_ZSTD #include "compress.h" diff --git a/src/conf.h b/src/conf.h index 6bc5942f..f975008c 100644 --- a/src/conf.h +++ b/src/conf.h @@ -380,6 +380,18 @@ struct UnsignedSizeOf { #define usizeof(expr) (UnsignedSizeOf::value) ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == sizeof(int)) +template +inline void mem_clear(T *object) noexcept { + static_assert(std::is_class_v); + static_assert(std::is_standard_layout_v); + static_assert(std::is_trivially_copyable_v); + static constexpr size_t size = sizeof(*object); + static_assert(size >= 1 && size <= UPX_RSIZE_MAX_MEM); + memset((void *) object, 0, size); +} +template +inline void mem_clear(T (&array)[N]) noexcept = delete; + // An Array allocates memory on the heap, and automatically // gets destructed when leaving scope or on exceptions. #define Array(type, var, n) \ @@ -582,12 +594,11 @@ typedef upx_callback_t *upx_callback_p; typedef void (__acc_cdecl *upx_progress_func_t) (upx_callback_p, unsigned, unsigned); -struct upx_callback_t -{ +struct upx_callback_t { upx_progress_func_t nprogress; void *user; - void reset() noexcept { memset(this, 0, sizeof(*this)); } + void reset() noexcept { mem_clear(this); } }; @@ -640,8 +651,7 @@ inline void oassign(T &v, const OptVar &other) { } -struct lzma_compress_config_t -{ +struct lzma_compress_config_t { typedef OptVar pos_bits_t; // pb typedef OptVar lit_pos_bits_t; // lp typedef OptVar lit_context_bits_t; // lc @@ -661,13 +671,11 @@ struct lzma_compress_config_t void reset() noexcept; }; -struct ucl_compress_config_t : public REAL_ucl_compress_config_t -{ +struct ucl_compress_config_t : public REAL_ucl_compress_config_t { void reset() noexcept { memset(this, 0xff, sizeof(*this)); } }; -struct zlib_compress_config_t -{ +struct zlib_compress_config_t { typedef OptVar mem_level_t; // ml typedef OptVar window_bits_t; // wb typedef OptVar strategy_t; // st @@ -679,19 +687,18 @@ struct zlib_compress_config_t void reset() noexcept; }; -struct zstd_compress_config_t -{ +struct zstd_compress_config_t { unsigned dummy; void reset() noexcept; }; -struct upx_compress_config_t -{ +struct upx_compress_config_t { lzma_compress_config_t conf_lzma; ucl_compress_config_t conf_ucl; zlib_compress_config_t conf_zlib; zstd_compress_config_t conf_zstd; + void reset() noexcept { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); conf_zstd.reset(); } }; @@ -702,8 +709,7 @@ struct upx_compress_config_t // compression - result_t **************************************************************************/ -struct lzma_compress_result_t -{ +struct lzma_compress_result_t { unsigned pos_bits; // pb unsigned lit_pos_bits; // lp unsigned lit_context_bits; // lc @@ -713,37 +719,35 @@ struct lzma_compress_result_t unsigned match_finder_cycles; unsigned num_probs; // (computed result) - void reset() noexcept { memset(this, 0, sizeof(*this)); } + void reset() noexcept { mem_clear(this); } }; -struct ucl_compress_result_t -{ +struct ucl_compress_result_t { ucl_uint result[16]; - void reset() noexcept { memset(this, 0, sizeof(*this)); } + void reset() noexcept { mem_clear(this); } }; -struct zlib_compress_result_t -{ +struct zlib_compress_result_t { unsigned dummy; - void reset() noexcept { memset(this, 0, sizeof(*this)); } + void reset() noexcept { mem_clear(this); } }; -struct zstd_compress_result_t -{ +struct zstd_compress_result_t { unsigned dummy; - void reset() noexcept { memset(this, 0, sizeof(*this)); } + void reset() noexcept { mem_clear(this); } }; -struct upx_compress_result_t -{ +struct upx_compress_result_t { // debugging aid - struct { + struct Debug { int method, level; unsigned u_len, c_len; - } debug; + void reset() noexcept { mem_clear(this); } + }; + Debug debug; lzma_compress_result_t result_lzma; ucl_compress_result_t result_ucl; @@ -751,7 +755,7 @@ struct upx_compress_result_t zstd_compress_result_t result_zstd; void reset() noexcept { - memset(&this->debug, 0, sizeof(this->debug)); + debug.reset(); result_lzma.reset(); result_ucl.reset(); result_zlib.reset(); result_zstd.reset(); } }; diff --git a/src/lefile.cpp b/src/lefile.cpp index c0c0c276..76ce9d58 100644 --- a/src/lefile.cpp +++ b/src/lefile.cpp @@ -34,8 +34,8 @@ LeFile::LeFile(InputFile *f) : fif(f), fof(nullptr), le_offset(0), exe_offset(0) COMPILE_TIME_ASSERT(sizeof(le_header_t) == 196) COMPILE_TIME_ASSERT(sizeof(le_object_table_entry_t) == 24) COMPILE_TIME_ASSERT(sizeof(le_pagemap_entry_t) == 4) - memset(&ih, 0, sizeof ih); - memset(&oh, 0, sizeof oh); + mem_clear(&ih); + mem_clear(&oh); } LeFile::~LeFile() { @@ -257,7 +257,7 @@ void LeFile::writeFile(OutputFile *f, bool le) { void LeFile::countFixups(unsigned *counts) const { const unsigned o = objects; - memset(counts, 0, sizeof(unsigned) * (o + 2)); + memset(counts, 0, mem_size(sizeof(unsigned), o + 2)); // counts[0..objects-1] - # of 32-bit offset relocations in for that objects // counts[objects] - # of selector fixups // counts[objects+1] - # of self-relative fixups diff --git a/src/options.cpp b/src/options.cpp index 9072285a..f29bb170 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -40,7 +40,7 @@ std::mutex opt_lock_mutex; void Options::reset() noexcept { Options *const o = this; - mem_clear(o, sizeof(*o)); + mem_clear(o); o->crp.reset(); o->cmd = CMD_NONE; diff --git a/src/p_exe.cpp b/src/p_exe.cpp index e720f0ac..d32a1e26 100644 --- a/src/p_exe.cpp +++ b/src/p_exe.cpp @@ -72,7 +72,7 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const { if (ih.relocs == 0) flag |= NORELOC; - memset(&oh, 0, sizeof(oh)); + mem_clear(&oh); oh.ident = 'M' + 'Z' * 256; oh.headsize16 = 2; @@ -656,7 +656,7 @@ void PackExe::unpack(OutputFile *fo) { } // fill new exe header - memset(&oh, 0, sizeof(oh)); + mem_clear(&oh); oh.ident = 'M' + 'Z' * 256; if (relocnum) { diff --git a/src/p_wcle.cpp b/src/p_wcle.cpp index b3170df4..7d441bb9 100644 --- a/src/p_wcle.cpp +++ b/src/p_wcle.cpp @@ -174,8 +174,9 @@ void PackWcle::readObjectTable() { void PackWcle::encodeObjectTable() { unsigned ic, jc; - oobject_table = New(le_object_table_entry_t, soobject_table = 2); - memset(oobject_table, 0, soobject_table * sizeof(*oobject_table)); + soobject_table = 2; + oobject_table = New(le_object_table_entry_t, soobject_table); + memset(oobject_table, 0, mem_size(sizeof(*oobject_table), soobject_table)); // object #1: OOT(0, base_address) = IOT(0, base_address); diff --git a/src/packer.cpp b/src/packer.cpp index f3f1329e..3e501f98 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -43,7 +43,7 @@ Packer::Packer(InputFile *f) file_size = fi->st_size(); mem_size_assert(1, file_size_u); uip = new UiPacker(this); - mem_clear(&ph, sizeof(ph)); + mem_clear(&ph); } Packer::~Packer() noexcept { @@ -599,7 +599,7 @@ unsigned Packer::getRandomId() const { // this is called directly after the constructor from class PackMaster void Packer::initPackHeader() { - mem_clear(&ph, sizeof(ph)); + mem_clear(&ph); ph.version = getVersion(); ph.format = getFormat(); ph.method = M_NONE; diff --git a/src/pefile.cpp b/src/pefile.cpp index 3a20b230..6e9ff9d7 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -1067,7 +1067,7 @@ PeFile::Export::Export(char *_base) : base(_base), iv(_base) { COMPILE_TIME_ASSERT_ALIGNED1(export_dir_t) ename = functionptrs = ordinals = nullptr; names = nullptr; - memset(&edir, 0, sizeof(edir)); + mem_clear(&edir); size = 0; } diff --git a/src/ui.cpp b/src/ui.cpp index e6e7634b..82ac4939 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -162,7 +162,7 @@ UiPacker::UiPacker(const Packer *p_) : ui_pass(0), ui_total_passes(0), p(p_), s( cb.reset(); s = new State; - memset(s, 0, sizeof(*s)); + mem_clear(s); s->msg_buf[0] = '\r'; #if defined(UI_USE_SCREEN) diff --git a/src/util/membuffer.h b/src/util/membuffer.h index 4390bf5b..7ecb1e05 100644 --- a/src/util/membuffer.h +++ b/src/util/membuffer.h @@ -185,7 +185,7 @@ private: void *last_return_address_dealloc; void *last_return_address_fill; void *last_return_address_subref; - Debug() noexcept { memset(this, 0, sizeof(*this)); } + Debug() noexcept { mem_clear(this); } }; Debug debug; #endif diff --git a/src/util/util.h b/src/util/util.h index 9e6d0518..3618a769 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -66,12 +66,6 @@ inline void mem_size_assert(upx_uint64_t element_size, upx_uint64_t n) { (void) mem_size(element_size, n); // assert size } -// will throw on invalid size -inline void mem_clear(void *p, size_t n) { - (void) mem_size(1, n); // assert size - memset(p, 0, n); -} - // "new" with asserted size; will throw on invalid size #if DEBUG template diff --git a/src/work.cpp b/src/work.cpp index 0aff1674..0dcb2b86 100644 --- a/src/work.cpp +++ b/src/work.cpp @@ -61,7 +61,7 @@ void do_one_file(const char *iname, char *oname) { int r; struct stat st; - memset(&st, 0, sizeof(st)); + mem_clear(&st); #if (HAVE_LSTAT) r = lstat(iname, &st); #else @@ -106,7 +106,7 @@ void do_one_file(const char *iname, char *oname) { #if (USE_FTIME) struct ftime fi_ftime; - memset(&fi_ftime, 0, sizeof(fi_ftime)); + mem_clear(&fi_ftime); if (opt->preserve_timestamp) { if (getftime(fi.getFd(), &fi_ftime) != 0) throwIOException("cannot determine file timestamp");