1 Star 1 Fork 0

OnlyVersion/upx

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
main.cpp 42.80 KB
一键复制 编辑 原始数据 按行查看 历史
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550
/* main.cpp --
This file is part of the UPX executable compressor.
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2017 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar
*/
#include "conf.h"
#include "compress.h"
#include "file.h"
#include "packer.h"
#include "p_elf.h"
#if 1 && defined(__DJGPP__)
#include <crt0.h>
int _crt0_startup_flags = _CRT0_FLAG_UNIX_SBRK;
#endif
/*************************************************************************
// options
**************************************************************************/
void options_t::reset()
{
options_t *o = this;
memset(o, 0, sizeof(*o));
o->crp.reset();
o->cmd = CMD_NONE;
o->method = M_NONE;
o->level = -1;
o->filter = FT_NONE;
o->backup = -1;
o->overlay = -1;
o->preserve_mode = true;
o->preserve_ownership = true;
o->preserve_timestamp = true;
o->console = CON_FILE;
#if defined(__DJGPP__)
o->console = CON_INIT;
#elif (USE_SCREEN_WIN32)
o->console = CON_INIT;
#elif 1 && defined(__linux__)
o->console = CON_INIT;
#endif
o->verbose = 2;
o->win32_pe.compress_exports = 1;
o->win32_pe.compress_icons = 2;
o->win32_pe.compress_resources = -1;
for (unsigned i = 0; i < TABLESIZE(o->win32_pe.compress_rt); i++)
o->win32_pe.compress_rt[i] = -1;
o->win32_pe.compress_rt[24] = false; // 24 == RT_MANIFEST
o->win32_pe.strip_relocs = -1;
o->win32_pe.keep_resource = "";
}
static options_t global_options;
options_t *opt = &global_options;
static int done_output_name = 0;
const char *argv0 = "";
const char *progname = "";
static acc_getopt_t mfx_getopt;
#define mfx_optarg mfx_getopt.optarg
#define mfx_optind mfx_getopt.optind
#define mfx_option acc_getopt_longopt_t
static void handle_opterr(acc_getopt_p g, const char *f, void *v)
{
struct A { va_list ap; };
struct A *a = (struct A *) v;
fprintf( stderr, "%s: ", g->progname);
vfprintf(stderr, f, a->ap);
fprintf( stderr, "\n");
}
static int num_files = -1;
static int exit_code = EXIT_OK;
/*************************************************************************
// exit handlers
**************************************************************************/
#if defined(__GNUC__)
static void do_exit(void) __attribute__((__noreturn__));
#endif
static void do_exit(void)
{
static bool in_exit = false;
if (in_exit)
exit(exit_code);
in_exit = true;
fflush(con_term);
fflush(stderr);
exit(exit_code);
}
#define EXIT_FATAL 3
static bool set_eec(int ec, int *eec)
{
if (ec == EXIT_FATAL)
{
*eec = EXIT_ERROR;
return 1;
}
else if (ec < 0 || ec == EXIT_ERROR)
{
*eec = EXIT_ERROR;
}
else if (ec == EXIT_WARN)
{
if (!opt->ignorewarn)
if (*eec == EXIT_OK)
*eec = ec;
}
else if (ec == EXIT_OK)
{
/* do nothing */
}
else
{
assert(0);
}
return 0;
}
bool set_exit_code(int ec)
{
return set_eec(ec,&exit_code);
}
void e_exit(int ec)
{
(void) set_exit_code(ec);
do_exit();
}
static void e_usage(void)
{
show_usage();
e_exit(EXIT_USAGE);
}
#if 0 // UNUSED
static void e_memory(void)
{
show_head();
fflush(con_term);
fprintf(stderr,"%s: out of memory\n", argv0);
e_exit(EXIT_MEMORY);
}
#endif // UNUSED
static void e_method(int m, int l)
{
fflush(con_term);
fprintf(stderr,"%s: illegal method option -- %d/%d\n", argv0, m, l);
e_usage();
}
static void e_optarg(const char *n)
{
fflush(con_term);
fprintf(stderr,"%s: invalid argument in option '%s'\n", argv0, n);
e_exit(EXIT_USAGE);
}
static void e_optval(const char *n)
{
fflush(con_term);
fprintf(stderr,"%s: invalid value for option '%s'\n", argv0, n);
e_exit(EXIT_USAGE);
}
#if defined(OPTIONS_VAR)
static void e_envopt(const char *n)
{
fflush(con_term);
if (n)
fprintf(stderr,"%s: invalid string '%s' in environment variable '%s'\n",
argv0, n, OPTIONS_VAR);
else
fprintf(stderr,"%s: illegal option in environment variable '%s'\n",
argv0, OPTIONS_VAR);
e_exit(EXIT_USAGE);
}
#endif /* defined(OPTIONS_VAR) */
#if 0 // UNUSED
static void __acc_cdecl_sighandler e_sighandler(int signum)
{
UNUSED(signum);
e_exit(EXIT_FATAL);
}
#endif // UNUSED
/*************************************************************************
// check options
**************************************************************************/
static void check_not_both(bool e1, bool e2, const char *c1, const char *c2)
{
if (e1 && e2)
{
fprintf(stderr,"%s: ",argv0);
fprintf(stderr,"cannot use both '%s' and '%s'\n", c1, c2);
e_usage();
}
}
static void check_options(int i, int argc)
{
assert(i <= argc);
if (opt->cmd != CMD_COMPRESS)
{
// invalidate compression options
opt->method = 0;
opt->level = 0;
opt->exact = 0;
opt->small = 0;
opt->crp.reset();
}
// set default overlay action
if (!(opt->cmd == CMD_COMPRESS || opt->cmd == CMD_DECOMPRESS))
opt->overlay = opt->COPY_OVERLAY;
else if (opt->overlay < 0)
opt->overlay = opt->COPY_OVERLAY;
check_not_both(opt->exact, opt->overlay == opt->STRIP_OVERLAY, "--exact", "--overlay=strip");
// set default backup option
if (opt->backup < 0)
opt->backup = 0;
if (!(opt->cmd == CMD_COMPRESS || opt->cmd == CMD_DECOMPRESS))
opt->backup = 1;
check_not_both(opt->to_stdout, opt->output_name != NULL, "--stdout", "-o");
if (opt->to_stdout && opt->cmd == CMD_COMPRESS)
{
fprintf(stderr,"%s: cannot use '--stdout' when compressing\n", argv0);
e_usage();
}
if (opt->to_stdout || opt->output_name)
{
if (i + 1 != argc)
{
fprintf(stderr,"%s: need exactly one argument when using '%s'\n",
argv0, opt->to_stdout ? "--stdout" : "-o");
e_usage();
}
}
}
/*************************************************************************
// misc
**************************************************************************/
static void e_help(void)
{
show_help();
e_exit(EXIT_USAGE);
}
static void set_term(FILE *f)
{
if (f)
con_term = f;
else
con_term = acc_isatty(STDIN_FILENO) ? stderr : stdout;
}
static void set_cmd(int cmd)
{
if (cmd > opt->cmd)
opt->cmd = cmd;
}
static bool set_method(int m, int l)
{
if (m > 0)
{
if (!Packer::isValidCompressionMethod(m))
return false;
// something like "--brute --lzma" should not disable "--brute"
if (!opt->all_methods)
opt->method = m;
}
if (l > 0)
opt->level = l;
set_cmd(CMD_COMPRESS);
return true;
}
static void set_output_name(const char *n, bool allow_m)
{
#if 1
if (done_output_name > 0)
{
fprintf(stderr,"%s: option '-o' more than once given\n",argv0);
e_usage();
}
#endif
if (!n || !n[0] || (!allow_m && n[0] == '-'))
{
fprintf(stderr,"%s: missing output name\n",argv0);
e_usage();
}
if (strlen(n) >= ACC_FN_PATH_MAX - 4)
{
fprintf(stderr,"%s: output name too long\n",argv0);
e_usage();
}
opt->output_name = n;
done_output_name++;
}
/*************************************************************************
// get options
**************************************************************************/
static
char* prepare_shortopts(char *buf, const char *n,
const struct mfx_option *longopts)
{
char *o = buf;
for ( ; n && *n; n++)
if (*n != ' ')
*o++ = *n;
*o = 0;
for ( ; longopts && longopts->name; longopts++)
{
int v = longopts->val;
#if !defined(NDEBUG)
assert(longopts->name[0] != '\0');
assert(longopts->name[0] != '-');
if (longopts->has_arg & 0x20)
assert((longopts->has_arg & 0xf) == 1);
#endif
#if 0
static char vopts[1024];
if (v > 0 && v < 1024)
{
if (vopts[v] && strchr(buf,v) == NULL)
printf("warning: duplicate option %d ('%c')!\n", v, v & 127);
vopts[v] = 1;
}
#endif
if (v > 0 && v < 256 && strchr(buf,v) == NULL)
{
*o++ = (char) v;
if ((longopts->has_arg & 0xf) >= 1)
*o++ = ':';
if ((longopts->has_arg & 0xf) >= 2)
*o++ = ':';
*o = 0;
}
if (longopts->has_arg & 0x20)
assert((longopts->has_arg & 0xf) == 1);
}
return buf;
}
template <class T>
static int getoptvar(T *var, const T min_value, const T max_value, const char *arg_fatal)
{
const char *p = mfx_optarg;
char *endptr;
int r = 0;
long n;
T v;
if (!p || !p[0])
{ r = -1; goto error; }
// avoid interpretation as octal value
while (p[0] == '0' && isdigit(p[1]))
p++;
n = strtol(p, &endptr, 0);
if (*endptr != '\0')
{ r = -2; goto error; }
v = (T) n;
if (v < min_value)
{ r = -3; goto error; }
if (v > max_value)
{ r = -4; goto error; }
*var = v;
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>
static int getoptvar(OptVar<T,default_value,min_value,max_value> *var, const char *arg_fatal)
{
T v = default_value;
int r = getoptvar(&v, min_value, max_value, arg_fatal);
if (r == 0)
*var = v;
return r;
}
static int do_option(int optc, const char *arg)
{
int i = 0;
switch (optc)
{
#if 0
// FIXME: to_stdout doesn't work because of console code mess
//case 'c':
case 517:
opt->to_stdout = true;
break;
#endif
case 'd':
set_cmd(CMD_DECOMPRESS);
break;
case 'D':
opt->debug.debug_level++;
break;
case 'f':
opt->force++;
break;
case 909:
set_cmd(CMD_FILEINFO);
break;
case 'h':
case 'H':
case '?':
set_cmd(CMD_HELP);
break;
case 'h'+256:
#if 1
if (!acc_isatty(STDOUT_FILENO))
{
/* according to GNU standards */
set_term(stdout);
opt->console = CON_FILE;
}
#endif
show_help(1);
e_exit(EXIT_OK);
break;
case 'i':
opt->info_mode++;
break;
case 'l':
set_cmd(CMD_LIST);
break;
case 'L':
set_cmd(CMD_LICENSE);
break;
case 'o':
set_output_name(mfx_optarg,1);
break;
case 'q':
opt->verbose = (opt->verbose > 1 ? 1 : opt->verbose - 1);
break;
case 't':
set_cmd(CMD_TEST);
break;
case 'v':
opt->verbose = (opt->verbose < 3 ? 3 : opt->verbose + 1);
break;
case 'V':
set_cmd(CMD_VERSION);
break;
case 'V'+256:
/* according to GNU standards */
set_term(stdout);
opt->console = CON_FILE;
show_version(0);
e_exit(EXIT_OK);
break;
// method
case 702:
opt->method_nrv2b_seen = true;
if (!set_method(M_NRV2B_LE32, -1))
e_method(M_NRV2B_LE32, opt->level);
break;
case 704:
opt->method_nrv2d_seen = true;
if (!set_method(M_NRV2D_LE32, -1))
e_method(M_NRV2D_LE32, opt->level);
break;
case 705:
opt->method_nrv2e_seen = true;
if (!set_method(M_NRV2E_LE32, -1))
e_method(M_NRV2E_LE32, opt->level);
break;
case 721:
opt->method_lzma_seen = true;
opt->all_methods_use_lzma = true;
if (!set_method(M_LZMA, -1))
e_method(M_LZMA, opt->level);
break;
case 722:
opt->method_lzma_seen = false;
opt->all_methods_use_lzma = false;
if (M_IS_LZMA(opt->method))
opt->method = -1;
break;
case 723:
opt->prefer_ucl = false;
break;
case 724:
opt->prefer_ucl = true;
break;
// compression level
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (!set_method(-1, optc - '0'))
e_method(opt->method, optc);
break;
case 902: // --ultra-brute
opt->ultra_brute = true;
/* fallthrough */
case 901: // --brute
opt->all_methods = true;
opt->all_methods_use_lzma = true;
opt->method = -1;
opt->all_filters = true;
opt->filter = -1;
opt->crp.crp_ucl.m_size = 999999;
/* fallthrough */
case 900: // --best
if (!set_method(-1, 10))
e_method(opt->method, 10);
break;
// debug
case 542:
if (!mfx_optarg || strlen(mfx_optarg) != 4)
e_optarg(arg);
memcpy(opt->debug.fake_stub_version, mfx_optarg, 4);
break;
case 543:
if (!mfx_optarg || strlen(mfx_optarg) != 4)
e_optarg(arg);
memcpy(opt->debug.fake_stub_year, mfx_optarg, 4);
break;
case 544:
if (!mfx_optarg || !mfx_optarg[0])
e_optarg(arg);
opt->debug.dump_stub_loader = mfx_optarg;
break;
case 545:
opt->debug.disable_random_id = true;
break;
// mp (meta)
case 501:
getoptvar(&opt->mp_compress_task, 1, 999999, arg);
break;
case 502:
opt->mp_query_format = true;
break;
case 503:
opt->mp_query_num_tasks = true;
break;
// misc
case 512:
opt->console = CON_FILE;
break;
case 513:
opt->console = CON_ANSI_MONO;
break;
case 514:
opt->console = CON_ANSI_COLOR;
break;
case 516:
opt->no_progress = true;
break;
case 519:
opt->no_env = true;
break;
case 526:
opt->preserve_mode = false;
break;
case 527:
opt->preserve_ownership = false;
break;
case 528:
opt->preserve_timestamp = false;
break;
// compression settings
case 520: // --small
if (opt->small < 0)
opt->small = 0;
opt->small++;
break;
case 521: // --filter=
getoptvar(&opt->filter, 0, 255, arg);
opt->all_filters = false;
break;
case 522: // --no-filter
opt->filter = 0;
opt->all_filters = false;
opt->no_filter = true;
break;
case 523: // --all-filters
opt->all_filters = true;
opt->filter = -1;
break;
case 524: // --all-methods
opt->all_methods = true;
opt->all_methods_use_lzma = true;
opt->method = -1;
break;
case 525: // --exact
opt->exact = true;
break;
// compression runtime parameters
case 801:
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg);
break;
case 802:
getoptvar(&opt->crp.crp_ucl.s_level, 0, 2, arg);
break;
case 803:
getoptvar(&opt->crp.crp_ucl.h_level, 0, 1, arg);
break;
case 804:
getoptvar(&opt->crp.crp_ucl.p_level, 0, 7, arg);
break;
case 805:
getoptvar(&opt->crp.crp_ucl.max_offset, 256u, ~0u, arg);
break;
case 806:
getoptvar(&opt->crp.crp_ucl.max_match, 16u, ~0u, arg);
break;
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;
case 814:
getoptvar(&opt->crp.crp_lzma.dict_size, arg);
break;
case 816:
getoptvar(&opt->crp.crp_lzma.num_fast_bytes, arg);
break;
case 821:
getoptvar(&opt->crp.crp_zlib.mem_level, arg);
break;
case 822:
getoptvar(&opt->crp.crp_zlib.window_bits, arg);
break;
case 823:
getoptvar(&opt->crp.crp_zlib.strategy, arg);
break;
// backup
case 'k':
opt->backup = 1;
break;
case 541:
if (opt->backup != 1) // do not overide '--backup'
opt->backup = 0;
break;
// overlay
case 551:
if (mfx_optarg && strcmp(mfx_optarg,"skip") == 0)
opt->overlay = opt->SKIP_OVERLAY;
else if (mfx_optarg && strcmp(mfx_optarg,"copy") == 0)
opt->overlay = opt->COPY_OVERLAY;
else if (mfx_optarg && strcmp(mfx_optarg,"strip") == 0)
opt->overlay = opt->STRIP_OVERLAY;
else
e_optarg(arg);
break;
case 552:
opt->overlay = opt->SKIP_OVERLAY;
break;
case 553:
opt->overlay = opt->COPY_OVERLAY;
break;
case 554:
opt->overlay = opt->STRIP_OVERLAY;
break;
// CPU
case 560:
if (mfx_optarg && strcmp(mfx_optarg,"8086") == 0)
opt->cpu = opt->CPU_8086;
else if (mfx_optarg && strcmp(mfx_optarg,"386") == 0)
opt->cpu = opt->CPU_386;
else if (mfx_optarg && strcmp(mfx_optarg,"486") == 0)
opt->cpu = opt->CPU_486;
else
e_optarg(arg);
break;
case 561:
opt->cpu = opt->CPU_8086;
break;
case 563:
opt->cpu = opt->CPU_386;
break;
case 564:
opt->cpu = opt->CPU_486;
break;
//
case 600:
opt->dos_exe.force_stub = true;
break;
case 601:
opt->dos_exe.no_reloc = true;
break;
case 610:
opt->djgpp2_coff.coff = true;
break;
case 620:
opt->watcom_le.le = true;
break;
case 630:
opt->win32_pe.compress_exports = 1;
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.compress_exports, 0, 1, arg);
//printf("compress_exports: %d\n", opt->win32_pe.compress_exports);
break;
case 631:
opt->win32_pe.compress_icons = 1;
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.compress_icons, 0, 3, arg);
//printf("compress_icons: %d\n", opt->win32_pe.compress_icons);
break;
case 632:
opt->win32_pe.compress_resources = 1;
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.compress_resources, 0, 1, arg);
//printf("compress_resources: %d\n", opt->win32_pe.compress_resources);
break;
case 633:
// opt->win32_pe.strip_loadconf - OBSOLETE - IGNORED
break;
case 634:
opt->win32_pe.strip_relocs = 1;
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.strip_relocs, 0, 1, arg);
//printf("strip_relocs: %d\n", opt->win32_pe.strip_relocs);
break;
case 635:
if (!mfx_optarg || !mfx_optarg[0])
e_optarg(arg);
opt->win32_pe.keep_resource = mfx_optarg;
break;
case 650:
opt->atari_tos.split_segments = true;
break;
case 660:
getoptvar(&opt->o_unix.blocksize, 8192u, ~0u, arg);
break;
case 661:
opt->o_unix.force_execve = true;
break;
case 663:
opt->o_unix.is_ptinterp = true;
break;
case 664:
opt->o_unix.use_ptinterp = true;
break;
case 665:
opt->o_unix.make_ptinterp = true;
break;
case 666: // Linux
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_LINUX;
break;
case 667: // FreeBSD
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_FREEBSD;
break;
case 668: // NetBSD
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_NETBSD;
break;
case 669: // OpenBSD
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_OPENBSD;
break;
case 670:
opt->ps1_exe.boot_only = true;
break;
case 671:
opt->ps1_exe.no_align = true;
opt->ps1_exe.boot_only = false;
break;
case 672:
opt->ps1_exe.do_8bit = true;
break;
case 673:
opt->ps1_exe.do_8mib = false;
break;
case 674:
opt->o_unix.unmap_all_pages = true; // val ?
break;
case 675:
opt->o_unix.preserve_build_id = true;
break;
case '\0':
return -1;
case ':':
return -2;
default:
fprintf(stderr,"%s: internal error in getopt (%d)\n", argv0, optc);
return -3;
}
UNUSED(i);
return 0;
}
static int get_options(int argc, char **argv)
{
static const struct mfx_option longopts[] =
{
// commands
{"best", 0x10, 0, 900}, // compress best
{"brute", 0x10, 0, 901}, // compress best, brute force
{"ultra-brute", 0x10, 0, 902}, // compress best, brute force
{"decompress", 0, 0, 'd'}, // decompress
{"fast", 0x10, 0, '1'}, // compress faster
{"fileinfo", 0x10, 0, 909}, // display info about file
{"file-info", 0x10, 0, 909}, // display info about file
{"help", 0, 0, 'h'+256}, // give help
{"license", 0, 0, 'L'}, // display software license
{"list", 0, 0, 'l'}, // list compressed exe
{"test", 0, 0, 't'}, // test compressed file integrity
{"uncompress", 0, 0, 'd'}, // decompress
{"version", 0, 0, 'V'+256}, // display version number
// options
{"force", 0, 0, 'f'}, // force overwrite of output files
{"force-compress", 0, 0, 'f'}, // and compression of suspicious files
{"info", 0, 0, 'i'}, // info mode
{"no-env", 0x10, 0, 519}, // no environment var
{"no-mode", 0x10, 0, 526}, // do not preserve mode (permissions)
{"no-owner", 0x10, 0, 527}, // do not preserve ownership
{"no-progress", 0, 0, 516}, // no progress bar
{"no-time", 0x10, 0, 528}, // do not preserve timestamp
{"output", 0x21, 0, 'o'},
{"quiet", 0, 0, 'q'}, // quiet mode
{"silent", 0, 0, 'q'}, // quiet mode
#if 0
// FIXME: to_stdout doesn't work because of console code mess
{"stdout", 0x10, 0, 517}, // write output on standard output
{"to-stdout", 0x10, 0, 517}, // write output on standard output
#endif
{"verbose", 0, 0, 'v'}, // verbose mode
// debug options
{"debug", 0x10, 0, 'D'},
{"dump-stub-loader" ,0x31, 0, 544}, // for internal debugging
{"fake-stub-version",0x31, 0, 542}, // for internal debugging
{"fake-stub-year" ,0x31, 0, 543}, // for internal debugging
{"disable-random-id",0x10, 0, 545}, // for internal debugging
// backup options
{"backup", 0x10, 0, 'k'},
{"keep", 0x10, 0, 'k'},
{"no-backup", 0x10, 0, 541},
// overlay options
{"overlay", 0x31, 0, 551}, // --overlay=
{"skip-overlay", 0x10, 0, 552},
{"no-overlay", 0x10, 0, 552}, // old name
{"copy-overlay", 0x10, 0, 553},
{"strip-overlay", 0x10, 0, 554},
// CPU options
{"cpu", 0x31, 0, 560}, // --cpu=
{"8086", 0x10, 0, 561},
{"386", 0x10, 0, 563},
{"486", 0x10, 0, 564},
// color options
{"no-color", 0x10, 0, 512},
{"mono", 0x10, 0, 513},
{"color", 0x10, 0, 514},
// compression method
{"nrv2b", 0x10, 0, 702}, // --nrv2b
{"nrv2d", 0x10, 0, 704}, // --nrv2d
{"nrv2e", 0x10, 0, 705}, // --nrv2e
{"lzma", 0x10, 0, 721}, // --lzma
{"no-lzma", 0x10, 0, 722}, // disable all_methods_use_lzma
{"prefer-nrv", 0x10, 0, 723},
{"prefer-ucl", 0x10, 0, 724},
// compression settings
{"all-filters", 0x10, 0, 523},
{"all-methods", 0x10, 0, 524},
{"exact", 0x10, 0, 525}, // user requires byte-identical decompression
{"filter", 0x31, 0, 521}, // --filter=
{"no-filter", 0x10, 0, 522},
{"small", 0x10, 0, 520},
// compression runtime parameters
{"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},
{"crp-lzma-ds", 0x31, 0, 814},
{"crp-lzma-fb", 0x31, 0, 816},
{"crp-zlib-ml", 0x31, 0, 821},
{"crp-zlib-wb", 0x31, 0, 822},
{"crp-zlib-st", 0x31, 0, 823},
// [deprecated - only for compatibility with UPX 2.0x]
{"crp-ms", 0x31, 0, 807},
// atari/tos
{"split-segments", 0x10, 0, 650},
// djgpp2/coff
{"coff", 0x10, 0, 610}, // produce COFF output
// dos/com
// dos/exe
//{"force-stub", 0x10, 0, 600},
{"no-reloc", 0x10, 0, 601}, // no reloc. record into packer dos/exe
// dos/sys
// unix
{"blocksize", 0x31, 0, 660}, // --blocksize=
{"force-execve", 0x10, 0, 661}, // force linux/386 execve format
{"is_ptinterp", 0x10, 0, 663}, // linux/elf386 PT_INTERP program
{"use_ptinterp", 0x10, 0, 664}, // linux/elf386 PT_INTERP program
{"make_ptinterp", 0x10, 0, 665}, // linux/elf386 PT_INTERP program
{"Linux", 0x10, 0, 666},
{"linux", 0x10, 0, 666},
{"FreeBSD", 0x10, 0, 667},
{"freebsd", 0x10, 0, 667},
{"NetBSD", 0x10, 0, 668},
{"netbsd", 0x10, 0, 668},
{"OpenBSD", 0x10, 0, 669},
{"openbsd", 0x10, 0, 669},
{"unmap-all-pages", 0x10, 0, 674}, // linux /proc/self/exe vanishes
{"preserve-build-id", 0, 0, 675},
// watcom/le
{"le", 0x10, 0, 620}, // produce LE output
// win32/pe
{"compress-exports", 2, 0, 630},
{"compress-icons", 2, 0, 631},
{"compress-resources", 2, 0, 632},
{"strip-loadconf", 0x12, 0, 633}, // OBSOLETE - IGNORED
{"strip-relocs", 0x12, 0, 634},
{"keep-resource", 0x31, 0, 635},
// ps1/exe
{"boot-only", 0x10, 0, 670},
{"no-align", 0x10, 0, 671},
{"8-bit", 0x10, 0, 672},
{"8mib-ram", 0x10, 0, 673},
{"8mb-ram", 0x10, 0, 673},
// mp (meta) options
{"mp-compress-task", 0x31, 0, 501},
{"mp-query-format", 0x10, 0, 502},
{"mp-query-num-tasks", 0x10, 0, 503},
{ NULL, 0, NULL, 0 }
};
int optc, longind;
char shortopts[256];
prepare_shortopts(shortopts, "123456789hH?V", longopts),
acc_getopt_init(&mfx_getopt, 1, argc, argv);
mfx_getopt.progname = progname;
mfx_getopt.opterr = handle_opterr;
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_LINUX;
while ((optc = acc_getopt(&mfx_getopt, shortopts, longopts, &longind)) >= 0)
{
if (do_option(optc, argv[mfx_optind-1]) != 0)
e_usage();
}
return mfx_optind;
}
#if defined(OPTIONS_VAR)
static void get_envoptions(int argc, char **argv)
{
/* only some options are allowed in the environment variable */
static const struct mfx_option longopts[] =
{
// commands
{"best", 0x10, 0, 900}, // compress best
{"brute", 0x10, 0, 901}, // compress best, brute force
{"ultra-brute", 0x10, 0, 902}, // compress best, brute force
{"fast", 0x10, 0, '1'}, // compress faster
// options
{"info", 0, 0, 'i'}, // info mode
{"no-progress", 0, 0, 516}, // no progress bar
{"quiet", 0, 0, 'q'}, // quiet mode
{"silent", 0, 0, 'q'}, // quiet mode
{"verbose", 0, 0, 'v'}, // verbose mode
// debug options
{"disable-random-id",0x10, 0, 545}, // for internal debugging
// backup options
{"backup", 0x10, 0, 'k'},
{"keep", 0x10, 0, 'k'},
{"no-backup", 0x10, 0, 541},
// overlay options
{"overlay", 0x31, 0, 551}, // --overlay=
{"skip-overlay", 0x10, 0, 552},
{"no-overlay", 0x10, 0, 552}, // old name
{"copy-overlay", 0x10, 0, 553},
{"strip-overlay", 0x10, 0, 554},
// CPU options
{"cpu", 0x31, 0, 560}, // --cpu=
{"8086", 0x10, 0, 561},
{"386", 0x10, 0, 563},
{"486", 0x10, 0, 564},
// color options
{"no-color", 0x10, 0, 512},
{"mono", 0x10, 0, 513},
{"color", 0x10, 0, 514},
// compression settings
{"exact", 0x10, 0, 525}, // user requires byte-identical decompression
// compression method
{"nrv2b", 0x10, 0, 702}, // --nrv2b
{"nrv2d", 0x10, 0, 704}, // --nrv2d
{"nrv2e", 0x10, 0, 705}, // --nrv2e
{"lzma", 0x10, 0, 721}, // --lzma
{"no-lzma", 0x10, 0, 722}, // disable all_methods_use_lzma
{"prefer-nrv", 0x10, 0, 723},
{"prefer-ucl", 0x10, 0, 724},
// compression settings
// compression runtime parameters
// win32/pe
{"compress-exports", 2, 0, 630},
{"compress-icons", 2, 0, 631},
{"compress-resources", 2, 0, 632},
{"strip-loadconf", 0x12, 0, 633}, // OBSOLETE - IGNORED
{"strip-relocs", 0x12, 0, 634},
{"keep-resource", 0x31, 0, 635},
{ NULL, 0, NULL, 0 }
};
char *env, *p;
const char *var;
int i, optc, longind;
int targc;
char **targv = NULL;
static const char sep[] = " \t";
char shortopts[256];
var = getenv(OPTIONS_VAR);
if (var == NULL || !var[0])
return;
env = strdup(var);
if (env == NULL)
return;
/* count arguments */
for (p = env, targc = 1; ; )
{
while (*p && strchr(sep,*p))
p++;
if (*p == '\0')
break;
targc++;
while (*p && !strchr(sep,*p))
p++;
if (*p == '\0')
break;
p++;
}
/* alloc temp argv */
if (targc > 1)
targv = (char **) calloc(targc+1,sizeof(char *));
if (targv == NULL)
{
free(env);
return;
}
/* fill temp argv */
targv[0] = argv[0];
for (p = env, targc = 1; ; )
{
while (*p && strchr(sep,*p))
p++;
if (*p == '\0')
break;
targv[targc++] = p;
while (*p && !strchr(sep,*p))
p++;
if (*p == '\0')
break;
*p++ = '\0';
}
targv[targc] = NULL;
/* check that only options are in temp argv */
for (i = 1; i < targc; i++)
if (targv[i][0] != '-' || !targv[i][1] || strcmp(targv[i],"--") == 0)
e_envopt(targv[i]);
/* handle options */
prepare_shortopts(shortopts, "123456789", longopts);
acc_getopt_init(&mfx_getopt, 1, targc, targv);
mfx_getopt.progname = progname;
mfx_getopt.opterr = handle_opterr;
while ((optc = acc_getopt(&mfx_getopt, shortopts, longopts, &longind)) >= 0)
{
if (do_option(optc, targv[mfx_optind-1]) != 0)
e_envopt(NULL);
}
if (mfx_optind < targc)
e_envopt(targv[mfx_optind]);
/* clean up */
free(targv);
free(env);
UNUSED(argc);
}
#endif /* defined(OPTIONS_VAR) */
static void first_options(int argc, char **argv)
{
int i;
int n = argc;
for (i = 1; i < n; i++)
{
if (strcmp(argv[i],"--") == 0)
{
n = i;
break;
}
if (strcmp(argv[i],"--version") == 0)
do_option('V'+256, argv[i]);
}
for (i = 1; i < n; i++)
if (strcmp(argv[i],"--help") == 0)
do_option('h'+256, argv[i]);
for (i = 1; i < n; i++)
if (strcmp(argv[i],"--no-env") == 0)
do_option(519, argv[i]);
}
/*************************************************************************
// assert a sane architecture and compiler
**************************************************************************/
template <class T> struct TestBELE {
static bool test(void)
{
COMPILE_TIME_ASSERT_ALIGNED1(T)
__packed_struct(test1_t) char a; T b; __packed_struct_end()
__packed_struct(test2_t) char a; T b[3]; __packed_struct_end()
test1_t t1[7]; UNUSED(t1); test2_t t2[7]; UNUSED(t2);
COMPILE_TIME_ASSERT(sizeof(test1_t) == 1 + sizeof(T))
COMPILE_TIME_ASSERT_ALIGNED1(test1_t)
COMPILE_TIME_ASSERT(sizeof(t1) == 7 + 7*sizeof(T))
COMPILE_TIME_ASSERT(sizeof(test2_t) == 1 + 3*sizeof(T))
COMPILE_TIME_ASSERT_ALIGNED1(test2_t)
COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21*sizeof(T))
#if defined(__acc_alignof)
COMPILE_TIME_ASSERT(__acc_alignof(t1) == 1)
COMPILE_TIME_ASSERT(__acc_alignof(t2) == 1)
#endif
#if 1 && !defined(UPX_OFFICIAL_BUILD)
T allbits; allbits = 0; allbits -= 1;
//++allbits; allbits++; --allbits; allbits--;
T v1; v1 = 1; v1 *= 2; v1 -= 1;
T v2; v2 = 1;
assert( (v1 == v2)); assert(!(v1 != v2));
assert( (v1 <= v2)); assert( (v1 >= v2));
assert(!(v1 < v2)); assert(!(v1 > v2));
v2 ^= allbits;
assert(!(v1 == v2)); assert( (v1 != v2));
assert( (v1 <= v2)); assert(!(v1 >= v2));
assert( (v1 < v2)); assert(!(v1 > v2));
v2 += 2;
assert(v1 == 1); assert(v2 == 0);
v1 <<= 1; v1 |= v2; v1 >>= 1; v2 &= v1; v2 /= v1; v2 *= v1;
assert(v1 == 1); assert(v2 == 0);
if ((v1 ^ v2) != 1) return false;
#endif
return true;
}};
#define ACC_WANT_ACC_CHK_CH 1
#undef ACCCHK_ASSERT
#include "miniacc.h"
__acc_static_noinline void upx_sanity_check(void)
{
#define ACC_WANT_ACC_CHK_CH 1
#undef ACCCHK_ASSERT
#define ACCCHK_ASSERT(expr) ACC_COMPILE_TIME_ASSERT(expr)
#include "miniacc.h"
#undef ACCCHK_ASSERT
COMPILE_TIME_ASSERT(sizeof(char) == 1)
COMPILE_TIME_ASSERT(sizeof(short) == 2)
COMPILE_TIME_ASSERT(sizeof(int) == 4)
COMPILE_TIME_ASSERT(sizeof(long) >= 4)
COMPILE_TIME_ASSERT(sizeof(void *) >= 4)
COMPILE_TIME_ASSERT(sizeof(off_t) >= sizeof(long))
COMPILE_TIME_ASSERT(((off_t) -1) < 0)
#if (ACC_OS_POSIX_DARWIN || ACC_OS_POSIX_LINUX)
COMPILE_TIME_ASSERT(sizeof(off_t) >= 8)
#endif
COMPILE_TIME_ASSERT(sizeof(BE16) == 2)
COMPILE_TIME_ASSERT(sizeof(BE32) == 4)
COMPILE_TIME_ASSERT(sizeof(BE64) == 8)
COMPILE_TIME_ASSERT(sizeof(LE16) == 2)
COMPILE_TIME_ASSERT(sizeof(LE32) == 4)
COMPILE_TIME_ASSERT(sizeof(LE64) == 8)
COMPILE_TIME_ASSERT_ALIGNED1(BE16)
COMPILE_TIME_ASSERT_ALIGNED1(BE32)
COMPILE_TIME_ASSERT_ALIGNED1(BE64)
COMPILE_TIME_ASSERT_ALIGNED1(LE16)
COMPILE_TIME_ASSERT_ALIGNED1(LE32)
COMPILE_TIME_ASSERT_ALIGNED1(LE64)
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_STRING4) == 4 + 1)
assert(strlen(UPX_VERSION_STRING4) == 4);
assert(memcmp(UPX_VERSION_STRING4, UPX_VERSION_STRING, 4) == 0);
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_YEAR) == 4 + 1)
assert(strlen(UPX_VERSION_YEAR) == 4);
assert(memcmp(UPX_VERSION_DATE_ISO, UPX_VERSION_YEAR, 4) == 0);
assert(memcmp(&UPX_VERSION_DATE[sizeof(UPX_VERSION_DATE)-1 - 4], UPX_VERSION_YEAR, 4) == 0);
if (gitrev[0]) {
size_t revlen = strlen(gitrev);
if (strncmp(gitrev, "ERROR", 5) == 0) { assert(revlen == 5 || revlen == 6); }
else { assert(revlen == 12 || revlen == 13); }
if (revlen == 6 || revlen == 13) { assert(gitrev[revlen-1] == '+'); }
}
#if 1
assert(TestBELE<LE16>::test());
assert(TestBELE<LE32>::test());
assert(TestBELE<LE64>::test());
assert(TestBELE<BE16>::test());
assert(TestBELE<BE32>::test());
assert(TestBELE<BE64>::test());
{
static const unsigned char dd[32]
#if 1 && (ACC_CC_CLANG || ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE) && defined(__ELF__)
__attribute__((__aligned__(16)))
#endif
= { 0, 0, 0, 0, 0, 0, 0,
0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
0, 0, 0, 0,
0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
0, 0, 0, 0, 0 };
const unsigned char *d;
const N_BELE_RTP::AbstractPolicy *bele;
d = dd + 7;
assert(upx_adler32(d, 4) == 0x09f003f7);
assert(upx_adler32(d, 4, 0) == 0x09ec03f6);
assert(upx_adler32(d, 4, 1) == 0x09f003f7);
bele = &N_BELE_RTP::be_policy;
assert(get_be16(d) == 0xfffe);
assert(bele->get16(d) == 0xfffe);
assert(get_be16_signed(d) == -2);
assert(get_be24(d) == 0xfffefd);
assert(bele->get24(d) == 0xfffefd);
assert(get_be24_signed(d) == -259);
assert(get_be32(d) == 0xfffefdfc);
assert(bele->get32(d) == 0xfffefdfc);
assert(get_be32_signed(d) == -66052);
bele = &N_BELE_RTP::le_policy;
assert(get_le16(d) == 0xfeff);
assert(bele->get16(d) == 0xfeff);
assert(get_le16_signed(d) == -257);
assert(get_le24(d) == 0xfdfeff);
assert(bele->get24(d) == 0xfdfeff);
assert(get_le24_signed(d) == -131329);
assert(get_le32(d) == 0xfcfdfeff);
assert(bele->get32(d) == 0xfcfdfeff);
assert(get_le32_signed(d) == -50462977);
assert(get_le64_signed(d) == UPX_INT64_C(-506097522914230529));
assert(find_be16(d, 2, 0xfffe) == 0);
assert(find_le16(d, 2, 0xfeff) == 0);
assert(find_be32(d, 4, 0xfffefdfc) == 0);
assert(find_le32(d, 4, 0xfcfdfeff) == 0);
d += 12;
assert(get_be16_signed(d) == 32638);
assert(get_be24_signed(d) == 8355453);
assert(get_be32_signed(d) == 2138996092);
assert(get_be64_signed(d) == UPX_INT64_C(9186918263483431288));
}
#endif
}
/*************************************************************************
// main entry point
**************************************************************************/
#if !(WITH_GUI)
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
extern "C" { extern long _stksize; long _stksize = 256 * 1024L; }
#endif
#if (ACC_OS_WIN32 || ACC_OS_WIN64) && (defined(__MINGW32__) || defined(__MINGW64__))
extern "C" { extern int _dowildcard; int _dowildcard = -1; }
#endif
int __acc_cdecl_main main(int argc, char *argv[])
{
int i;
static char default_argv0[] = "upx";
// int cmdline_cmd = CMD_NONE;
#if 0 && defined(__DJGPP__)
// LFN=n may cause problems with 2.03's _rename and mkdir under WinME
putenv("LFN=y");
#endif
#if (ACC_OS_WIN32 || ACC_OS_WIN64) && (ACC_CC_MSC) && defined(_WRITE_ABORT_MSG) && defined(_CALL_REPORTFAULT)
_set_abort_behavior(_WRITE_ABORT_MSG, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
#endif
acc_wildargv(&argc, &argv);
upx_sanity_check();
opt->reset();
if (!argv[0] || !argv[0][0])
argv[0] = default_argv0;
argv0 = argv[0];
#if (ACC_OS_CYGWIN || ACC_OS_DOS16 || ACC_OS_DOS32 || ACC_OS_EMX || ACC_OS_TOS || ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64)
{
char *prog = fn_basename(argv0);
char *p;
bool allupper = true;
for (p = prog; *p; p++)
if (islower((unsigned char)*p))
allupper = false;
if (allupper)
fn_strlwr(prog);
if (p - prog > 4)
{
p -= 4;
if (fn_strcmp(p, ".exe") == 0 || fn_strcmp(p, ".ttp") == 0)
*p = 0;
}
progname = prog;
}
#else
progname = fn_basename(argv0);
#endif
while (progname[0] == '.' && progname[1] == '/' && progname[2])
progname += 2;
set_term(stderr);
if (upx_ucl_init() != 0)
{
show_head();
fprintf(stderr,"ucl_init() failed - check your UCL installation !\n");
if (UCL_VERSION != ucl_version())
fprintf(stderr,"library version conflict (%lx, %lx) - check your UCL installation !\n",
(long) UCL_VERSION, (long) ucl_version());
e_exit(EXIT_INIT);
}
assert(upx_lzma_init() == 0);
assert(upx_zlib_init() == 0);
#if (WITH_NRV)
assert(upx_nrv_init() == 0);
#endif
//srand((int) time(NULL));
srand((int) clock());
/* get options */
first_options(argc,argv);
#if defined(OPTIONS_VAR)
if (!opt->no_env)
get_envoptions(argc,argv);
#endif
i = get_options(argc,argv);
assert(i <= argc);
set_term(NULL);
// cmdline_cmd = opt->cmd;
switch (opt->cmd)
{
case CMD_NONE:
/* default - compress */
set_cmd(CMD_COMPRESS);
break;
case CMD_COMPRESS:
break;
case CMD_DECOMPRESS:
break;
case CMD_TEST:
break;
case CMD_LIST:
break;
case CMD_FILEINFO:
break;
case CMD_LICENSE:
show_license();
e_exit(EXIT_OK);
break;
case CMD_HELP:
show_help(1);
e_exit(EXIT_OK);
break;
case CMD_VERSION:
show_version(1);
e_exit(EXIT_OK);
break;
default:
/* ??? */
break;
}
/* check options */
if (argc == 1)
e_help();
set_term(stderr);
check_options(i,argc);
num_files = argc - i;
if (num_files < 1)
{
if (opt->verbose >= 2)
e_help();
else
e_usage();
}
/* start work */
set_term(stdout);
do_files(i,argc,argv);
if (gitrev[0])
{
FILE *f = stdout;
int fg = con_fg(f,FG_RED);
con_fprintf(f,"\nWARNING: this is an unstable beta version - use for testing only! Really.\n");
fg = con_fg(f,fg);
UNUSED(fg);
}
#if 0 && defined(__GLIBC__)
//malloc_stats();
#endif
return exit_code;
}
#endif /* !(WITH_GUI) */
/* vim:set ts=4 sw=4 et: */
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/OnlyVersion/upx.git
[email protected]:OnlyVersion/upx.git
OnlyVersion
upx
upx
master

搜索帮助