diff --git a/src/conf.h b/src/conf.h index 8c87b6eb..98a80a8e 100644 --- a/src/conf.h +++ b/src/conf.h @@ -661,7 +661,6 @@ typedef ElfLinker Linker; // main.cpp extern const char *progname; -void init_options(struct options_t *o); bool set_ec(int ec); #if (ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE) void e_exit(int ec) __attribute__((__noreturn__)); diff --git a/src/help.cpp b/src/help.cpp index c735081a..dd6f4d0b 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -28,6 +28,8 @@ #include "conf.h" #include "compress.h" +#include "packmast.h" +#include "packer.h" /************************************************************************* @@ -85,6 +87,75 @@ void show_usage(void) } +/************************************************************************* +// +**************************************************************************/ + +struct PackerNames +{ + struct Entry { + const char* fname; + const char* sname; + }; + Entry names[32]; + size_t names_count; + const options_t *o; + PackerNames() { names_count = 0; o = NULL; } + void add(Packer *p) + { + assert(names_count < 32); + names[names_count].fname = p->getFullName(o); + names[names_count].sname = p->getName(); + names_count++; + } + static Packer* visit(Packer *p, void *user) + { + PackerNames *self = (PackerNames *) user; + self->add(p); + return NULL; + } + static int __acc_cdecl_qsort cmp_fname(const void *a, const void *b) { + return strcmp(((const Entry *) a)->fname, ((const Entry *) b)->fname); + } + static int __acc_cdecl_qsort cmp_sname(const void *a, const void *b) { + return strcmp(((const Entry *) a)->sname, ((const Entry *) b)->sname); + } +}; + +static void show_all_packers(FILE *f, int verbose) +{ + options_t o; o.reset(); + PackerNames pn; pn.o = &o; + PackMaster::visitAllPackers(pn.visit, NULL, &o, &pn); + qsort(pn.names, pn.names_count, sizeof(PackerNames::Entry), pn.cmp_fname); + size_t pos = 0; + for (size_t i = 0; i < pn.names_count; ++i) + { + const char *fn = pn.names[i].fname; + const char *sn = pn.names[i].sname; + if (verbose) + { + con_fprintf(f, " %-30s %s\n", fn, sn); + } + else + { + if (pos == 0) { + con_fprintf(f, " %s", fn); + pos = 2 + strlen(fn); + } else if (pos + 1 + strlen(fn) > 80) { + con_fprintf(f, "\n %s", fn); + pos = 2 + strlen(fn); + } else { + con_fprintf(f, " %s", fn); + pos += 1 + strlen(fn); + } + } + } + if (!verbose && pn.names_count) + con_fprintf(f, "\n"); +} + + /************************************************************************* // **************************************************************************/ @@ -245,38 +316,11 @@ void show_help(int x/*verbose*/) fg = con_fg(f,FG_YELLOW); con_fprintf(f,"This version supports:\n"); fg = con_fg(f,fg); - con_fprintf(f," " -// TODO: -// support for mach/ppc32 -// support for linux elf/ppc32 -// support for linux elf/amd64 - " arm/pe," - " atari/tos," - " bvmlinuz/386," - " djgpp2/coff," - " dos/com," - " dos/exe," - " dos/sys," - "\n " - //" elks/8086," - " linux/amd64," - " linux/i386," - " linux/ppc32," - " mach/ppc32," - " ps1/exe," - " rtm32/pe," - "\n " - " tmt/adam," - " vmlinux/386," - " vmlinuz/386," - " watcom/le," - //" win16/ne," - " win32/pe" - "\n\nUPX comes with ABSOLUTELY NO WARRANTY; for details visit http://upx.sf.net\n" -// "\n\nUPX comes with ABSOLUTELY NO WARRANTY; for details type `upx -L'.\n" + show_all_packers(f, x); + con_fprintf(f,"\nUPX comes with ABSOLUTELY NO WARRANTY; for details visit http://upx.sf.net\n" +// "\nUPX comes with ABSOLUTELY NO WARRANTY; for details type `upx -L'.\n" ""); - #if defined(DEBUG) || defined(TESTING) fg = con_fg(f,FG_RED); con_fprintf(f,"\nWARNING: this version is compiled with" diff --git a/src/main.cpp b/src/main.cpp index ab944301..4e6349a6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -77,8 +77,8 @@ void options_t::reset() o->win32_pe.keep_resource = ""; } -static struct options_t global_options; -struct options_t *opt = &global_options; +static options_t global_options; +options_t *opt = &global_options; static int done_output_name = 0; static int done_script_name = 0; diff --git a/src/packer.cpp b/src/packer.cpp index 1e6d8407..48d8396a 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -45,7 +45,8 @@ Packer::Packer(InputFile *f) : uip(NULL), linker(NULL), last_patch(NULL), last_patch_len(0), last_patch_off(0) { - file_size = f->st.st_size; + if (fi != NULL) + file_size = fi->st.st_size; uip = new UiPacker(this); memset(&ph, 0, sizeof(ph)); } @@ -66,6 +67,7 @@ void Packer::assertPacker() assert(getVersion() >= 11); assert(getVersion() <= 14); assert(strlen(getName()) <= 13); + assert(strlen(getFullName(opt)) <= 26); // "i386-linux.kernel.bvmlinuz" if (bele == NULL) fprintf(stderr, "%s\n", getName()); assert(bele != NULL); #if 1 diff --git a/src/packmast.cpp b/src/packmast.cpp index aa5d7674..5a132a1f 100644 --- a/src/packmast.cpp +++ b/src/packmast.cpp @@ -61,7 +61,7 @@ // **************************************************************************/ -PackMaster::PackMaster(InputFile *f, struct options_t *o) : +PackMaster::PackMaster(InputFile *f, options_t *o) : fi(f), p(NULL) { // replace options with local options @@ -90,12 +90,11 @@ PackMaster::~PackMaster() // **************************************************************************/ -typedef Packer* (*try_function)(Packer *p, InputFile *f); - -static Packer* try_pack(Packer *p, InputFile *f) +static Packer* try_pack(Packer *p, void *user) { if (p == NULL) return NULL; + InputFile *f = (InputFile *) user; p->assertPacker(); try { p->initPackHeader(); @@ -117,10 +116,11 @@ static Packer* try_pack(Packer *p, InputFile *f) } -static Packer* try_unpack(Packer *p, InputFile *f) +static Packer* try_unpack(Packer *p, void *user) { if (p == NULL) return NULL; + InputFile *f = (InputFile *) user; p->assertPacker(); try { p->initPackHeader(); @@ -150,7 +150,7 @@ static Packer* try_unpack(Packer *p, InputFile *f) // **************************************************************************/ -static Packer* try_packers(InputFile *f, try_function func) +Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const options_t *o, void *user) { Packer *p = NULL; @@ -159,124 +159,128 @@ static Packer* try_packers(InputFile *f, try_function func) // // .exe // - if (!opt->dos_exe.force_stub) + if (!o->dos_exe.force_stub) { - if ((p = func(new PackDjgpp2(f),f)) != NULL) + if ((p = func(new PackDjgpp2(f), user)) != NULL) return p; - if ((p = func(new PackTmt(f),f)) != NULL) + if ((p = func(new PackTmt(f), user)) != NULL) return p; - if ((p = func(new PackWcle(f),f)) != NULL) + if ((p = func(new PackWcle(f), user)) != NULL) return p; #if 0 - if ((p = func(new PackVxd(f),f)) != NULL) + if ((p = func(new PackVxd(f), user)) != NULL) return p; #endif - if ((p = func(new PackW16Ne(f),f)) != NULL) +#if 0 + if ((p = func(new PackW16Ne(f), user)) != NULL) return p; - if ((p = func(new PackArmPe(f),f)) != NULL) - return p; - if ((p = func(new PackW32Pe(f),f)) != NULL) +#endif + if ((p = func(new PackW32Pe(f), user)) != NULL) return p; } - if ((p = func(new PackExe(f),f)) != NULL) + if ((p = func(new PackArmPe(f), user)) != NULL) + return p; + if ((p = func(new PackExe(f), user)) != NULL) return p; // // atari // - if ((p = func(new PackTos(f),f)) != NULL) + if ((p = func(new PackTos(f), user)) != NULL) return p; // // linux kernel // - if ((p = func(new PackVmlinuxI386(f),f)) != NULL) + if ((p = func(new PackVmlinuxI386(f), user)) != NULL) return p; - if ((p = func(new PackVmlinuzI386(f),f)) != NULL) + if ((p = func(new PackVmlinuzI386(f), user)) != NULL) return p; - if ((p = func(new PackBvmlinuzI386(f),f)) != NULL) + if ((p = func(new PackBvmlinuzI386(f), user)) != NULL) return p; #if 0 - if ((p = func(new PackElks8086(f),f)) != NULL) + if ((p = func(new PackElks8086(f), user)) != NULL) return p; #endif // // linux // - if (!opt->o_unix.force_execve) + if (!o->o_unix.force_execve) { #if 0 - if (opt->unix.script_name) + if (o->unix.script_name) { - if ((p = func(new PackLinuxI386sep(f),f)) != NULL) + if ((p = func(new PackLinuxI386sep(f), user)) != NULL) return p; } #endif - if (opt->o_unix.use_ptinterp) { - if ((p = func(new PackLinuxElf32x86interp(f),f)) != NULL) + if (o->o_unix.use_ptinterp) { + if ((p = func(new PackLinuxElf32x86interp(f), user)) != NULL) return p; } - if ((p = func(new PackFreeBSDElf32x86(f),f)) != NULL) + if ((p = func(new PackFreeBSDElf32x86(f), user)) != NULL) return p; - if ((p = func(new PackNetBSDElf32x86(f),f)) != NULL) + if ((p = func(new PackNetBSDElf32x86(f), user)) != NULL) return p; - if ((p = func(new PackOpenBSDElf32x86(f),f)) != NULL) + if ((p = func(new PackOpenBSDElf32x86(f), user)) != NULL) return p; - if ((p = func(new PackLinuxElf32x86(f),f)) != NULL) + if ((p = func(new PackLinuxElf32x86(f), user)) != NULL) return p; - if ((p = func(new PackLinuxElf64amd(f),f)) != NULL) + if ((p = func(new PackLinuxElf64amd(f), user)) != NULL) return p; - if ((p = func(new PackLinuxElf32armLe(f),f)) != NULL) + if ((p = func(new PackLinuxElf32armLe(f), user)) != NULL) return p; - if ((p = func(new PackLinuxElf32armBe(f),f)) != NULL) + if ((p = func(new PackLinuxElf32armBe(f), user)) != NULL) return p; - if ((p = func(new PackLinuxElf32ppc(f),f)) != NULL) + if ((p = func(new PackLinuxElf32ppc(f), user)) != NULL) return p; - if ((p = func(new PackLinuxI386sh(f),f)) != NULL) + if ((p = func(new PackLinuxI386sh(f), user)) != NULL) return p; } - if ((p = func(new PackBSDI386(f),f)) != NULL) + if ((p = func(new PackBSDI386(f), user)) != NULL) return p; - if ((p = func(new PackLinuxI386(f),f)) != NULL) + if ((p = func(new PackLinuxI386(f), user)) != NULL) return p; // // psone // - if ((p = func(new PackPs1(f),f)) != NULL) + if ((p = func(new PackPs1(f), user)) != NULL) return p; // // .sys and .com // - if ((p = func(new PackSys(f),f)) != NULL) + if ((p = func(new PackSys(f), user)) != NULL) return p; - if ((p = func(new PackCom(f),f)) != NULL) + if ((p = func(new PackCom(f), user)) != NULL) return p; // Mach (MacOS X PowerPC) - if ((p = func(new PackMachPPC32(f), f)) != NULL) + if ((p = func(new PackMachPPC32(f), user)) != NULL) return p; return NULL; } -static Packer *getPacker(InputFile *f) +Packer *PackMaster::getPacker(InputFile *f) { - Packer *p = try_packers(f, try_pack); + Packer *p = visitAllPackers(try_pack, f, opt, f); if (!p) throwUnknownExecutableFormat(); + p->assertPacker(); return p; } -static Packer *getUnpacker(InputFile *f) +Packer *PackMaster::getUnpacker(InputFile *f) { - Packer *p = try_packers(f, try_unpack); + Packer *p = visitAllPackers(try_unpack, f, opt, f); if (!p) throwNotPacked(); + p->assertPacker(); return p; } @@ -288,7 +292,6 @@ static Packer *getUnpacker(InputFile *f) void PackMaster::pack(OutputFile *fo) { p = getPacker(fi); - p->assertPacker(); fi = NULL; p->doPack(fo); } @@ -306,7 +309,6 @@ void PackMaster::unpack(OutputFile *fo) void PackMaster::test() { p = getUnpacker(fi); - p->assertPacker(); fi = NULL; p->doTest(); } @@ -315,7 +317,6 @@ void PackMaster::test() void PackMaster::list() { p = getUnpacker(fi); - p->assertPacker(); fi = NULL; p->doList(); } @@ -323,9 +324,9 @@ void PackMaster::list() void PackMaster::fileInfo() { - p = try_packers(fi, try_unpack); + p = visitAllPackers(try_unpack, fi, opt, fi); if (!p) - p = try_packers(fi, try_pack); + p = visitAllPackers(try_pack, fi, opt, fi); if (!p) throwUnknownExecutableFormat(NULL, 1); // make a warning here p->assertPacker(); diff --git a/src/packmast.h b/src/packmast.h index 6326ef3b..4b9cdc60 100644 --- a/src/packmast.h +++ b/src/packmast.h @@ -41,7 +41,7 @@ class OutputFile; class PackMaster { public: - PackMaster(InputFile *f, struct options_t *o = NULL); + PackMaster(InputFile *f, options_t *o = NULL); virtual ~PackMaster(); void pack(OutputFile *fo); @@ -50,13 +50,19 @@ public: void list(); void fileInfo(); + typedef Packer* (*visit_func_t)(Packer *p, void *user); + static Packer* visitAllPackers(visit_func_t, InputFile *f, const options_t *, void *user); + private: InputFile *fi; Packer *p; + static Packer *getPacker(InputFile *f); + static Packer *getUnpacker(InputFile *f); + // setup local options for each file - struct options_t local_options; - struct options_t *saved_opt; + options_t local_options; + options_t *saved_opt; };