diff --git a/src/compress_lzma.cpp b/src/compress_lzma.cpp index ba79a4c2..22575dfa 100644 --- a/src/compress_lzma.cpp +++ b/src/compress_lzma.cpp @@ -234,6 +234,17 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len, goto error; } + // cconf overrides + if (cconf_parm) + { + if (cconf_parm->conf_lzma.pos_bits.is_set) + pr[0].uintVal = cconf_parm->conf_lzma.pos_bits; + if (cconf_parm->conf_lzma.lit_pos_bits.is_set) + pr[1].uintVal = cconf_parm->conf_lzma.lit_pos_bits; + if (cconf_parm->conf_lzma.lit_context_bits.is_set) + pr[2].uintVal = cconf_parm->conf_lzma.lit_context_bits; + } + // limit dictionary size if (pr[3].uintVal > src_len) pr[3].uintVal = src_len; @@ -269,6 +280,8 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len, //res->num_probs = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) res->num_probs = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits)); + printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs); + #ifndef _NO_EXCEPTIONS try { #else @@ -391,6 +404,9 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len, assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp); assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc); assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties)); + const lzma_compress_result_t *res = &cresult->result_lzma; + UNUSED(res); + printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs); } s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties)); if (!s.Probs) diff --git a/src/conf.h b/src/conf.h index 1909e75a..bd49e16a 100644 --- a/src/conf.h +++ b/src/conf.h @@ -212,19 +212,52 @@ struct upx_callback_t }; + +/************************************************************************* +// +**************************************************************************/ + +template +struct OptVar +{ + OptVar() : v(default_value), is_set(0) { } + OptVar& operator= (const OptVar& other) { + if (other.is_set) { v = other.v; is_set += 1; } + return *this; + } + OptVar& operator= (const T other) { + v = other; is_set += 1; return *this; + } + + void reset() { v = default_value; is_set = 0; } + operator T () const { return v; } + + T v; + unsigned is_set; +}; + + struct lzma_compress_config_t { - unsigned max_num_probs; + typedef OptVar pos_bits_t; // pb + typedef OptVar lit_pos_bits_t; // lb + typedef OptVar lit_context_bits_t; // lc + + unsigned max_num_probs; + pos_bits_t pos_bits; // pb + lit_pos_bits_t lit_pos_bits; // lp + lit_context_bits_t lit_context_bits; // lc #if 0 - unsigned pos_bits; // pb - unsigned lit_pos_bits; // lp - unsigned lit_context_bits; // lc unsigned dict_size; unsigned mf_passes; #endif - void reset() { memset(this, 0, sizeof(*this)); } + void reset() { + memset(this, 0, sizeof(*this)); + pos_bits.reset(); lit_pos_bits.reset(); lit_context_bits.reset(); + } }; + #define upx_compress_config_p upx_compress_config_t * struct upx_compress_config_t { diff --git a/src/main.cpp b/src/main.cpp index 437019e0..b0498f49 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,8 +43,9 @@ int _crt0_startup_flags = _CRT0_FLAG_UNIX_SBRK; // options **************************************************************************/ -void init_options(struct options_t *o) +void options_t::reset() { + options_t *o = this; memset(o, 0, sizeof(*o)); o->crp.reset(); @@ -405,26 +406,44 @@ char* prepare_shortopts(char *buf, const char *n, template -int getoptvar(T *var, const T minval, const T maxval) +int getoptvar(T *var, const T minval, const T maxval, const char *arg_fatal=NULL) { const char *p = mfx_optarg; char *endptr; + int r = 0; + long n; + T v; if (!p || !p[0]) - return -1; + { r = -1; goto error; } // avoid interpretation as octal value while (p[0] == '0' && isdigit(p[1])) p++; - long n = strtol(p, &endptr, 0); + n = strtol(p, &endptr, 0); if (*endptr != '\0') - return -2; - T v = (T) n; + { r = -2; goto error; } + v = (T) n; if (v < minval) - return -3; + { r = -3; goto error; } if (v > maxval) - return -4; + { r = -4; goto error; } *var = v; - return 0; + goto done; +error: + if (arg_fatal != NULL) + e_optval(arg_fatal); +done: + return r; +} + +template +int getoptvar(OptVar *var, const char *arg_fatal=NULL) +{ + T v = default_value; + int r = getoptvar(&v, min_value, max_value, arg_fatal); + if (r == 0) + *var = v; + return r; } @@ -602,27 +621,35 @@ static int do_option(int optc, const char *arg) opt->method = -1; break; // compression runtime parameters - case 531: + case 801: getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3); break; - case 532: + case 802: getoptvar(&opt->crp.crp_ucl.s_level, 0, 2); break; - case 533: + case 803: getoptvar(&opt->crp.crp_ucl.h_level, 0, 1); break; - case 534: + case 804: getoptvar(&opt->crp.crp_ucl.p_level, 0, 7); break; - case 535: + case 805: getoptvar(&opt->crp.crp_ucl.max_offset, 256u, ~0u); break; - case 536: + case 806: getoptvar(&opt->crp.crp_ucl.max_match, 16u, ~0u); break; - case 537: - if (getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u) != 0) - e_optval("--crp-ms="); + case 807: + getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u, arg); + break; + case 811: + getoptvar(&opt->crp.crp_lzma.pos_bits, arg); + break; + case 812: + getoptvar(&opt->crp.crp_lzma.lit_pos_bits, arg); + break; + case 813: + getoptvar(&opt->crp.crp_lzma.lit_context_bits, arg); break; // backup case 'k': @@ -854,13 +881,23 @@ static const struct mfx_option longopts[] = {"no-filter", 0x10, 0, 522}, {"small", 0x10, 0, 520}, // compression runtime parameters - {"crp-cf", 0x31, 0, 531}, - {"crp-sl", 0x31, 0, 532}, - {"crp-hl", 0x31, 0, 533}, - {"crp-pl", 0x31, 0, 534}, - {"crp-mo", 0x31, 0, 535}, - {"crp-mm", 0x31, 0, 536}, - {"crp-ms", 0x31, 0, 537}, + {"crp-nrv-cf", 0x31, 0, 801}, + {"crp-nrv-sl", 0x31, 0, 802}, + {"crp-nrv-hl", 0x31, 0, 803}, + {"crp-nrv-pl", 0x31, 0, 804}, + {"crp-nrv-mo", 0x31, 0, 805}, + {"crp-nrv-mm", 0x31, 0, 806}, + {"crp-nrv-ms", 0x31, 0, 807}, + {"crp-ucl-cf", 0x31, 0, 801}, + {"crp-ucl-sl", 0x31, 0, 802}, + {"crp-ucl-hl", 0x31, 0, 803}, + {"crp-ucl-pl", 0x31, 0, 804}, + {"crp-ucl-mo", 0x31, 0, 805}, + {"crp-ucl-mm", 0x31, 0, 806}, + {"crp-ucl-ms", 0x31, 0, 807}, + {"crp-lzma-pb", 0x31, 0, 811}, + {"crp-lzma-lp", 0x31, 0, 812}, + {"crp-lzma-lc", 0x31, 0, 813}, // atari/tos {"split-segments", 0x10, 0, 650}, @@ -963,13 +1000,6 @@ static const struct mfx_option longopts[] = {"color", 0, 0, 514}, // compression runtime parameters - {"crp-cf", 0x31, 0, 531}, - {"crp-sl", 0x31, 0, 532}, - {"crp-hl", 0x31, 0, 533}, - {"crp-pl", 0x31, 0, 534}, - {"crp-mo", 0x31, 0, 535}, - {"crp-mm", 0x31, 0, 536}, - {"crp-ms", 0x31, 0, 537}, // win32/pe {"compress-exports", 2, 0, 630}, @@ -1220,7 +1250,7 @@ int __acc_cdecl_main main(int argc, char *argv[]) acc_wildargv(&argc, &argv); upx_sanity_check(); - init_options(opt); + opt->reset(); if (!argv[0] || !argv[0][0]) argv[0] = default_argv0; diff --git a/src/options.h b/src/options.h index 396fbf46..cc24eba3 100644 --- a/src/options.h +++ b/src/options.h @@ -83,17 +83,20 @@ struct options_t { }; int overlay; - // compression runtime parameters - see struct ucl_compress_config_t + // compression runtime parameters - see struct XXX_compress_config_t struct crp_lzma_t { - int dummy; + typedef lzma_compress_config_t TT; + TT::pos_bits_t pos_bits; // pb + TT::lit_pos_bits_t lit_pos_bits; // lp + TT::lit_context_bits_t lit_context_bits; // lc #if 0 - unsigned pos_bits; // pb - unsigned lit_pos_bits; // lp - unsigned lit_context_bits; // lc unsigned dict_size; unsigned mf_passes; #endif - void reset() { memset(this, 0, sizeof(*this)); } + void reset() { + memset(this, 0, sizeof(*this)); + pos_bits.reset(); lit_pos_bits.reset(); lit_context_bits.reset(); + } }; struct crp_ucl_t { unsigned max_offset; @@ -162,6 +165,8 @@ struct options_t { int strip_relocs; const char *keep_resource; } win32_pe; + + void reset(); }; extern struct options_t *opt; diff --git a/src/packer.cpp b/src/packer.cpp index c3e4e912..2dd09cf3 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -189,6 +189,13 @@ bool Packer::compress(upx_bytep in, upx_bytep out, step = 0; #endif } + if (M_IS_LZMA(ph.method)) + { + // info: these are optional assignments which query OptVar::is_set + cconf.conf_lzma.pos_bits = opt->crp.crp_lzma.pos_bits; + cconf.conf_lzma.lit_pos_bits = opt->crp.crp_lzma.lit_pos_bits; + cconf.conf_lzma.lit_context_bits = opt->crp.crp_lzma.lit_context_bits; + } if (uip->ui_pass >= 0) uip->ui_pass++; uip->startCallback(ph.u_len, step, uip->ui_pass, uip->ui_total_passes);