1
0
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:
Markus F.X.J. Oberhumer 2006-10-12 13:47:15 +02:00
parent 407a9e5be0
commit 0ef3f75d7a
5 changed files with 135 additions and 44 deletions

View File

@ -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)

View File

@ -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
{
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
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
{

View File

@ -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 <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;
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 <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;
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;

View File

@ -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;

View File

@ -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);