diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e35eaff5..fab0e93a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,8 +13,8 @@ env: CTEST_OUTPUT_ON_FAILURE: "ON" DEBIAN_FRONTEND: noninteractive UPX_CMAKE_BUILD_FLAGS: --verbose - # 2023-10-23 - ZIG_DIST_VERSION: 0.12.0-dev.1200+5f92b070b + # 2023-10-24 + ZIG_DIST_VERSION: 0.12.0-dev.1245+a07f288eb jobs: job-rebuild-and-verify-stubs: diff --git a/.github/workflows/weekly-ci-cc-zigcc.yml b/.github/workflows/weekly-ci-cc-zigcc.yml index 07f90b44..eb63d339 100644 --- a/.github/workflows/weekly-ci-cc-zigcc.yml +++ b/.github/workflows/weekly-ci-cc-zigcc.yml @@ -11,8 +11,8 @@ env: CMAKE_REQUIRED_QUIET: "OFF" CTEST_OUTPUT_ON_FAILURE: "ON" DEBIAN_FRONTEND: noninteractive - # 2023-10-23 - ZIG_DIST_VERSION: 0.12.0-dev.1200+5f92b070b + # 2023-10-24 + ZIG_DIST_VERSION: 0.12.0-dev.1245+a07f288eb jobs: job-linux-zigcc: # uses cmake + make diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d84752d..c1dc6942 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -281,6 +281,30 @@ if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC") endif() endif() +# compile a source file with -O2 even in Debug build +function(upx_compile_source_debug_with_O2) + set(flags "$<$:-O2>") + if (CMAKE_VERSION VERSION_LESS 3.8) + # 3.8: The COMPILE_FLAGS source file property learned to support generator expressions + if (is_multi_config OR NOT CMAKE_BUILD_TYPE MATCHES "^Debug$") + return() + endif() + set(flags "-O2") + endif() + foreach(t ${ARGV}) + if(MSVC_FRONTEND) + # MSVC uses some Debug compilation options like -RTC1 that are incompatible with -O2 + else() + get_source_file_property(prop ${t} COMPILE_FLAGS) + if(prop MATCHES "^(NOTFOUND)?$") + set_source_files_properties(${t} PROPERTIES COMPILE_FLAGS "${flags}") + else() + set_source_files_properties(${t} PROPERTIES COMPILE_FLAGS "${prop} ${flags}") + endif() + endif() + endforeach() +endfunction() + # compile a target with -O2 even in Debug build function(upx_compile_target_debug_with_O2) foreach(t ${ARGV}) @@ -456,6 +480,9 @@ if(HAVE_UTIMENSAT) target_compile_definitions(${t} PRIVATE HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC=1) endif() endif() +# improve speed of the debug versions +upx_compile_source_debug_with_O2(src/compress/compress_lzma.cpp) +upx_compile_source_debug_with_O2(src/filter/filter_impl.cpp) #upx_compile_target_debug_with_O2(${t}) upx_sanitize_target(${t}) if(MSVC_FRONTEND) @@ -473,6 +500,7 @@ endif() if(NOT UPX_CONFIG_CMAKE_DISABLE_TEST) include(CTest) +# TODO later: check CMAKE_CROSSCOMPILING_EMULATOR if(NOT CMAKE_CROSSCOMPILING) add_test(NAME upx-version COMMAND upx --version) add_test(NAME upx-help COMMAND upx --help) diff --git a/src/p_w32pe_i386.cpp b/src/p_w32pe_i386.cpp index 532301a9..10741611 100644 --- a/src/p_w32pe_i386.cpp +++ b/src/p_w32pe_i386.cpp @@ -233,9 +233,9 @@ void PackW32PeI386::defineSymbols(unsigned ncsection, unsigned upxsection, unsig // linker->dumpSymbols(); } -void PackW32PeI386::addNewRelocations(Reloc &rel, unsigned base) { +void PackW32PeI386::addNewRelocations(Reloc &rel, unsigned upxsection) { if (use_stub_relocs) - rel.add(base + linker->getSymbolOffset("PESOCREL") + 1, 3); + rel.add(upxsection + linker->getSymbolOffset("PESOCREL") + 1, 3); } void PackW32PeI386::setOhDataBase(const pe_section_t *osection) { oh.database = osection[2].vaddr; } diff --git a/src/pefile.cpp b/src/pefile.cpp index 943d5e6e..43c6203b 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -454,13 +454,6 @@ void PeFile::Reloc::finish(byte *(&result_ptr), unsigned &result_size) { #endif } -void PeFile::processRelocs(Reloc *rel) // pass2 -{ - rel->finish(oxrelocs, soxrelocs); - if (opt->win32_pe.strip_relocs) - soxrelocs = 0; -} - void PeFile32::processRelocs() // pass1 { big_relocs = 0; @@ -483,8 +476,8 @@ void PeFile32::processRelocs() // pass1 ih.objects = tryremove(IDADDR(PEDIR_BASERELOC), ih.objects); } mb_orelocs.alloc(1); + mb_orelocs.clear(); orelocs = mb_orelocs; // => orelocs now is a SPAN_S - orelocs[0] = 0; // clear sorelocs = 0; return; } @@ -567,15 +560,17 @@ void PeFile64::processRelocs() // pass1 { big_relocs = 0; - const unsigned skip = IDADDR(PEDIR_BASERELOC); - const unsigned take = IDSIZE(PEDIR_BASERELOC); - Reloc rel(ibuf.subref("bad reloc %#x", skip, take), take); - const unsigned *counts = rel.getcounts(); + const unsigned skip1 = IDADDR(PEDIR_BASERELOC); + const unsigned take1 = IDSIZE(PEDIR_BASERELOC); + Reloc rel(ibuf.subref("bad reloc %#x", skip1, take1), take1); + const unsigned *const counts = rel.getcounts(); unsigned relocnum = 0; unsigned ic; for (ic = 1; ic < 16; ic++) relocnum += counts[ic]; + for (ic = 0; ic < 16; ic++) + NO_printf("reloc counts[%u] %u\n", ic, counts[ic]); if (opt->win32_pe.strip_relocs || relocnum == 0) { if (IDSIZE(PEDIR_BASERELOC)) { @@ -583,6 +578,7 @@ void PeFile64::processRelocs() // pass1 ih.objects = tryremove(IDADDR(PEDIR_BASERELOC), ih.objects); } mb_orelocs.alloc(1); + mb_orelocs.clear(); orelocs = mb_orelocs; // => orelocs now is a SPAN_S sorelocs = 0; return; @@ -2226,9 +2222,11 @@ void PeFile::callCompressWithFilters(Filter &ft, int filter_strategy, unsigned i compressWithFilters(&ft, 2048, NULL_cconf, filter_strategy, ih_codebase, rvamin, 0, nullptr, 0); } -void PeFile::callProcessRelocs(Reloc &rel, unsigned &ic) { +void PeFile::callProcessStubRelocs(Reloc &rel, unsigned &ic) { // WinCE wants relocation data at the beginning of a section - PeFile::processRelocs(&rel); + rel.finish(oxrelocs, soxrelocs); + if (opt->win32_pe.strip_relocs) + soxrelocs = 0; ODADDR(PEDIR_BASERELOC) = soxrelocs ? ic : 0; ODSIZE(PEDIR_BASERELOC) = soxrelocs; ic += soxrelocs; @@ -2456,7 +2454,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask, const unsigned ncsection = (s1addr + s1size + oam1) & ~oam1; const unsigned upxsection = s1addr + ic + c_len; - Reloc rel(1024); // new relocations are put here + Reloc rel(1024); // new stub relocations are put here addNewRelocations(rel, upxsection); // new PE header @@ -2497,7 +2495,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask, if (!last_section_rsrc_only) callProcessResources(res, ic); if (rel_at_sections_start) - callProcessRelocs(rel, ic); + callProcessStubRelocs(rel, ic); processImports2(ic, getProcessImportParam(upxsection)); ODADDR(PEDIR_IMPORT) = soimpdlls ? ic : 0; @@ -2514,7 +2512,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask, ic += soexport; if (!rel_at_sections_start) - callProcessRelocs(rel, ic); + callProcessStubRelocs(rel, ic); // when the resource is put alone into section 3 const unsigned res_start = (ic + oam1) & ~oam1; diff --git a/src/pefile.h b/src/pefile.h index f476bc6f..f4a47257 100644 --- a/src/pefile.h +++ b/src/pefile.h @@ -59,7 +59,7 @@ protected: virtual void defineSymbols(unsigned ncsection, unsigned upxsection, unsigned sizeof_oh, unsigned isize_isplit, unsigned s1addr) = 0; virtual void addNewRelocations(Reloc &, unsigned) {} - void callProcessRelocs(Reloc &rel, unsigned &ic); + void callProcessStubRelocs(Reloc &rel, unsigned &ic); void callProcessResources(Resource &res, unsigned &ic); virtual unsigned getProcessImportParam(unsigned) { return 0; } virtual void setOhDataBase(const pe_section_t *osection) = 0; @@ -106,7 +106,6 @@ protected: upx_uint64_t ilinkerGetAddress(const char *, const char *) const; virtual void processRelocs() = 0; - void processRelocs(Reloc *); void rebuildRelocs(SPAN_S(byte) &, unsigned bits, unsigned flags, upx_uint64_t imagebase); MemBuffer mb_orelocs; SPAN_0(byte) orelocs = nullptr; diff --git a/src/util/cxxlib.h b/src/util/cxxlib.h index ba6b77c0..c90cbeb8 100644 --- a/src/util/cxxlib.h +++ b/src/util/cxxlib.h @@ -134,11 +134,14 @@ struct TriBool final { } // "Third" can mean many things - depending on usage context, so provide some alternate names: +#if 0 // constexpr bool isDefault() const noexcept { return isThird(); } // might be misleading constexpr bool isIndeterminate() const noexcept { return isThird(); } + constexpr bool isNone() const noexcept { return isThird(); } constexpr bool isOther() const noexcept { return isThird(); } constexpr bool isUndecided() const noexcept { return isThird(); } // constexpr bool isUnset() const noexcept { return isThird(); } // might be misleading +#endif private: value_type value = False; // the actual value of this type