diff --git a/doc/upx.pod b/doc/upx.pod index 3beaf419..0d03ffd8 100644 --- a/doc/upx.pod +++ b/doc/upx.pod @@ -138,6 +138,9 @@ B<--help>: prints the help B<--version>: print the version of B +B<--exact>: when compressing, require to be able to get a byte-identical file +after decompression with option B<-d> + [ ...to be written... - type `B' for now ] diff --git a/src/except.cpp b/src/except.cpp index 4f3645bc..1295001a 100644 --- a/src/except.cpp +++ b/src/except.cpp @@ -85,6 +85,11 @@ void throwCantPack(const char *msg) throw CantUnpackException(msg); } +void throwCantPackExact() +{ + throwCantPack("option '--exact' does not work with this file"); +} + void throwFilterException() { throwCantPack("filter problem"); diff --git a/src/except.h b/src/except.h index 8c159d5b..e1d8dcba 100644 --- a/src/except.h +++ b/src/except.h @@ -208,6 +208,7 @@ public: #endif void throwCantPack(const char *msg) NORET; +void throwCantPackExact() NORET; void throwUnknownExecutableFormat(const char *msg = NULL, bool warn = false) NORET; void throwNotCompressible(const char *msg = NULL) NORET; void throwAlreadyPacked(const char *msg = NULL) NORET; diff --git a/src/main.cpp b/src/main.cpp index eddb4cd0..99c77ed1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -643,6 +643,9 @@ static int do_option(int optc, const char *arg) opt->all_methods = 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); @@ -918,6 +921,7 @@ static const struct mfx_option longopts[] = // 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}, @@ -1051,6 +1055,9 @@ static const struct mfx_option longopts[] = {"mono", 0x10, 0, 513}, {"color", 0x10, 0, 514}, + // compression settings + {"exact", 0x10, 0, 525}, // user requires byte-identical decompression + // compression runtime parameters // win32/pe @@ -1412,6 +1419,8 @@ int __acc_cdecl_main main(int argc, char *argv[]) // invalidate compression options opt->method = 0; opt->level = 0; + opt->exact = 0; + opt->small = 0; opt->crp.reset(); } diff --git a/src/options.h b/src/options.h index 735c37a9..bbf37363 100644 --- a/src/options.h +++ b/src/options.h @@ -53,6 +53,7 @@ struct options_t { bool all_methods_use_lzma; bool all_filters; // try all available filters ? bool no_filter; // force no filter + bool exact; // user requires byte-identical decompression // other options int backup; diff --git a/src/p_tos.cpp b/src/p_tos.cpp index 47bcee3c..9eb9bb30 100644 --- a/src/p_tos.cpp +++ b/src/p_tos.cpp @@ -439,6 +439,8 @@ void PackTos::pack(OutputFile *fo) t = i_text + i_data; fi->readx(ibuf,t); // skip symbols + if (i_sym && opt->exact) + throwCantPackExact(); fi->seek(i_sym,SEEK_CUR); // read relocations + overlay overlay = file_size - (FH_SIZE + i_text + i_data + i_sym);