mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
Introduced class OptVar for tracking optionally set options. Also
added three new options for finetuning lzma compression.
This commit is contained in:
parent
407a9e5be0
commit
0ef3f75d7a
|
@ -234,6 +234,17 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||||
goto error;
|
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
|
// limit dictionary size
|
||||||
if (pr[3].uintVal > src_len)
|
if (pr[3].uintVal > src_len)
|
||||||
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 = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
|
||||||
res->num_probs = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits));
|
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
|
#ifndef _NO_EXCEPTIONS
|
||||||
try {
|
try {
|
||||||
#else
|
#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_pos_bits == (unsigned) s.Properties.lp);
|
||||||
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
|
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
|
||||||
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
|
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));
|
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
||||||
if (!s.Probs)
|
if (!s.Probs)
|
||||||
|
|
43
src/conf.h
43
src/conf.h
|
@ -212,19 +212,52 @@ struct upx_callback_t
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
template <class T, T default_value, T min_value, T max_value>
|
||||||
|
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
|
struct lzma_compress_config_t
|
||||||
{
|
{
|
||||||
unsigned max_num_probs;
|
typedef OptVar<unsigned, 2u, 0u, 4u> pos_bits_t; // pb
|
||||||
|
typedef OptVar<unsigned, 0u, 0u, 4u> lit_pos_bits_t; // lb
|
||||||
|
typedef OptVar<unsigned, 3u, 0u, 8u> 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
|
#if 0
|
||||||
unsigned pos_bits; // pb
|
|
||||||
unsigned lit_pos_bits; // lp
|
|
||||||
unsigned lit_context_bits; // lc
|
|
||||||
unsigned dict_size;
|
unsigned dict_size;
|
||||||
unsigned mf_passes;
|
unsigned mf_passes;
|
||||||
#endif
|
#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 *
|
#define upx_compress_config_p upx_compress_config_t *
|
||||||
struct upx_compress_config_t
|
struct upx_compress_config_t
|
||||||
{
|
{
|
||||||
|
|
96
src/main.cpp
96
src/main.cpp
|
@ -43,8 +43,9 @@ int _crt0_startup_flags = _CRT0_FLAG_UNIX_SBRK;
|
||||||
// options
|
// options
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void init_options(struct options_t *o)
|
void options_t::reset()
|
||||||
{
|
{
|
||||||
|
options_t *o = this;
|
||||||
memset(o, 0, sizeof(*o));
|
memset(o, 0, sizeof(*o));
|
||||||
o->crp.reset();
|
o->crp.reset();
|
||||||
|
|
||||||
|
@ -405,26 +406,44 @@ char* prepare_shortopts(char *buf, const char *n,
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
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;
|
const char *p = mfx_optarg;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
int r = 0;
|
||||||
|
long n;
|
||||||
|
T v;
|
||||||
|
|
||||||
if (!p || !p[0])
|
if (!p || !p[0])
|
||||||
return -1;
|
{ r = -1; goto error; }
|
||||||
// avoid interpretation as octal value
|
// avoid interpretation as octal value
|
||||||
while (p[0] == '0' && isdigit(p[1]))
|
while (p[0] == '0' && isdigit(p[1]))
|
||||||
p++;
|
p++;
|
||||||
long n = strtol(p, &endptr, 0);
|
n = strtol(p, &endptr, 0);
|
||||||
if (*endptr != '\0')
|
if (*endptr != '\0')
|
||||||
return -2;
|
{ r = -2; goto error; }
|
||||||
T v = (T) n;
|
v = (T) n;
|
||||||
if (v < minval)
|
if (v < minval)
|
||||||
return -3;
|
{ r = -3; goto error; }
|
||||||
if (v > maxval)
|
if (v > maxval)
|
||||||
return -4;
|
{ r = -4; goto error; }
|
||||||
*var = v;
|
*var = v;
|
||||||
return 0;
|
goto done;
|
||||||
|
error:
|
||||||
|
if (arg_fatal != NULL)
|
||||||
|
e_optval(arg_fatal);
|
||||||
|
done:
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, T default_value, T min_value, T max_value>
|
||||||
|
int getoptvar(OptVar<T,default_value,min_value,max_value> *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;
|
opt->method = -1;
|
||||||
break;
|
break;
|
||||||
// compression runtime parameters
|
// compression runtime parameters
|
||||||
case 531:
|
case 801:
|
||||||
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3);
|
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3);
|
||||||
break;
|
break;
|
||||||
case 532:
|
case 802:
|
||||||
getoptvar(&opt->crp.crp_ucl.s_level, 0, 2);
|
getoptvar(&opt->crp.crp_ucl.s_level, 0, 2);
|
||||||
break;
|
break;
|
||||||
case 533:
|
case 803:
|
||||||
getoptvar(&opt->crp.crp_ucl.h_level, 0, 1);
|
getoptvar(&opt->crp.crp_ucl.h_level, 0, 1);
|
||||||
break;
|
break;
|
||||||
case 534:
|
case 804:
|
||||||
getoptvar(&opt->crp.crp_ucl.p_level, 0, 7);
|
getoptvar(&opt->crp.crp_ucl.p_level, 0, 7);
|
||||||
break;
|
break;
|
||||||
case 535:
|
case 805:
|
||||||
getoptvar(&opt->crp.crp_ucl.max_offset, 256u, ~0u);
|
getoptvar(&opt->crp.crp_ucl.max_offset, 256u, ~0u);
|
||||||
break;
|
break;
|
||||||
case 536:
|
case 806:
|
||||||
getoptvar(&opt->crp.crp_ucl.max_match, 16u, ~0u);
|
getoptvar(&opt->crp.crp_ucl.max_match, 16u, ~0u);
|
||||||
break;
|
break;
|
||||||
case 537:
|
case 807:
|
||||||
if (getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u) != 0)
|
getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u, arg);
|
||||||
e_optval("--crp-ms=");
|
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;
|
break;
|
||||||
// backup
|
// backup
|
||||||
case 'k':
|
case 'k':
|
||||||
|
@ -854,13 +881,23 @@ static const struct mfx_option longopts[] =
|
||||||
{"no-filter", 0x10, 0, 522},
|
{"no-filter", 0x10, 0, 522},
|
||||||
{"small", 0x10, 0, 520},
|
{"small", 0x10, 0, 520},
|
||||||
// compression runtime parameters
|
// compression runtime parameters
|
||||||
{"crp-cf", 0x31, 0, 531},
|
{"crp-nrv-cf", 0x31, 0, 801},
|
||||||
{"crp-sl", 0x31, 0, 532},
|
{"crp-nrv-sl", 0x31, 0, 802},
|
||||||
{"crp-hl", 0x31, 0, 533},
|
{"crp-nrv-hl", 0x31, 0, 803},
|
||||||
{"crp-pl", 0x31, 0, 534},
|
{"crp-nrv-pl", 0x31, 0, 804},
|
||||||
{"crp-mo", 0x31, 0, 535},
|
{"crp-nrv-mo", 0x31, 0, 805},
|
||||||
{"crp-mm", 0x31, 0, 536},
|
{"crp-nrv-mm", 0x31, 0, 806},
|
||||||
{"crp-ms", 0x31, 0, 537},
|
{"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
|
// atari/tos
|
||||||
{"split-segments", 0x10, 0, 650},
|
{"split-segments", 0x10, 0, 650},
|
||||||
|
@ -963,13 +1000,6 @@ static const struct mfx_option longopts[] =
|
||||||
{"color", 0, 0, 514},
|
{"color", 0, 0, 514},
|
||||||
|
|
||||||
// compression runtime parameters
|
// 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
|
// win32/pe
|
||||||
{"compress-exports", 2, 0, 630},
|
{"compress-exports", 2, 0, 630},
|
||||||
|
@ -1220,7 +1250,7 @@ int __acc_cdecl_main main(int argc, char *argv[])
|
||||||
acc_wildargv(&argc, &argv);
|
acc_wildargv(&argc, &argv);
|
||||||
|
|
||||||
upx_sanity_check();
|
upx_sanity_check();
|
||||||
init_options(opt);
|
opt->reset();
|
||||||
|
|
||||||
if (!argv[0] || !argv[0][0])
|
if (!argv[0] || !argv[0][0])
|
||||||
argv[0] = default_argv0;
|
argv[0] = default_argv0;
|
||||||
|
|
|
@ -83,17 +83,20 @@ struct options_t {
|
||||||
};
|
};
|
||||||
int overlay;
|
int overlay;
|
||||||
|
|
||||||
// compression runtime parameters - see struct ucl_compress_config_t
|
// compression runtime parameters - see struct XXX_compress_config_t
|
||||||
struct crp_lzma_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
|
#if 0
|
||||||
unsigned pos_bits; // pb
|
|
||||||
unsigned lit_pos_bits; // lp
|
|
||||||
unsigned lit_context_bits; // lc
|
|
||||||
unsigned dict_size;
|
unsigned dict_size;
|
||||||
unsigned mf_passes;
|
unsigned mf_passes;
|
||||||
#endif
|
#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 {
|
struct crp_ucl_t {
|
||||||
unsigned max_offset;
|
unsigned max_offset;
|
||||||
|
@ -162,6 +165,8 @@ struct options_t {
|
||||||
int strip_relocs;
|
int strip_relocs;
|
||||||
const char *keep_resource;
|
const char *keep_resource;
|
||||||
} win32_pe;
|
} win32_pe;
|
||||||
|
|
||||||
|
void reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct options_t *opt;
|
extern struct options_t *opt;
|
||||||
|
|
|
@ -189,6 +189,13 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
|
||||||
step = 0;
|
step = 0;
|
||||||
#endif
|
#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)
|
if (uip->ui_pass >= 0)
|
||||||
uip->ui_pass++;
|
uip->ui_pass++;
|
||||||
uip->startCallback(ph.u_len, step, uip->ui_pass, uip->ui_total_passes);
|
uip->startCallback(ph.u_len, step, uip->ui_pass, uip->ui_total_passes);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user