Merge branch 'devel4' of https://github.com/upx/upx into devel4
This commit is contained in:
commit
60093cfff6
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -377,8 +377,8 @@ jobs:
|
||||
- { zig_target: x86_64-macos.13-none }
|
||||
- { zig_target: x86_64-windows-gnu }
|
||||
env:
|
||||
# 2023-04-17
|
||||
ZIG_DIST_VERSION: 0.11.0-dev.2624+bc804eb84
|
||||
# 2023-04-24
|
||||
ZIG_DIST_VERSION: 0.11.0-dev.2777+b95cdf0ae
|
||||
# for zig-cc wrapper scripts (see below):
|
||||
ZIG_CPPFLAGS: -DUPX_DOCTEST_CONFIG_MULTITHREADING
|
||||
ZIG_FLAGS: ${{ matrix.zig_flags }}
|
||||
|
||||
@ -97,6 +97,11 @@ elseif(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
|
||||
endif()
|
||||
|
||||
set(MSVC_FRONTEND 0)
|
||||
if(MSVC OR ",${CMAKE_C_COMPILER_FRONTEND_VARIANT}," STREQUAL ",MSVC,")
|
||||
set(MSVC_FRONTEND 1)
|
||||
endif()
|
||||
|
||||
#***********************************************************************
|
||||
# targets
|
||||
#***********************************************************************
|
||||
@ -166,14 +171,14 @@ if(NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${b}" CACHE STRING "Flags used by the CXX compiler during RELEASE builds." FORCE)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(MSVC_FRONTEND)
|
||||
# disable silly warnings about using "deprecated" POSIX functions like fopen()
|
||||
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
add_definitions(-D_CRT_NONSTDC_NO_WARNINGS)
|
||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
# set __cplusplus according to selected C++ standard; use new preprocessor
|
||||
add_definitions(-Zc:__cplusplus -Zc:preprocessor)
|
||||
add_definitions(-J -Zc:__cplusplus -Zc:preprocessor)
|
||||
else()
|
||||
# protect against security threats caused by misguided compiler "optimizations"
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
@ -186,7 +191,7 @@ endif()
|
||||
|
||||
# compile a target with -O2 even in Debug build
|
||||
function(upx_compile_target_debug_with_O2 t)
|
||||
if(MSVC)
|
||||
if(MSVC_FRONTEND)
|
||||
# MSVC uses some Debug compile options like -RTC1 that are incompatible with -O2
|
||||
else()
|
||||
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-O2>)
|
||||
@ -195,7 +200,7 @@ endfunction()
|
||||
|
||||
function(upx_sanitize_target t)
|
||||
if(NOT UPX_CONFIG_DISABLE_SANITIZE)
|
||||
if(MSVC)
|
||||
if(MSVC_FRONTEND)
|
||||
# MSVC uses -GS (similar to -fstack-protector) by default
|
||||
elseif(CMAKE_C_PLATFORM_ID MATCHES "^MinGW" OR MINGW OR CYGWIN)
|
||||
# avoid link errors with current MinGW-w64 versions
|
||||
@ -213,8 +218,8 @@ set(t upx_vendor_ucl)
|
||||
target_include_directories(${t} PRIVATE vendor/ucl/include vendor/ucl)
|
||||
upx_compile_target_debug_with_O2(${t})
|
||||
upx_sanitize_target(${t})
|
||||
if(MSVC)
|
||||
target_compile_options(${t} PRIVATE -J ${warn_WN} ${warn_WX})
|
||||
if(MSVC_FRONTEND)
|
||||
target_compile_options(${t} PRIVATE ${warn_WN} ${warn_WX})
|
||||
else()
|
||||
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
|
||||
endif()
|
||||
@ -223,8 +228,8 @@ set(t upx_vendor_zlib)
|
||||
upx_compile_target_debug_with_O2(${t})
|
||||
upx_sanitize_target(${t})
|
||||
target_compile_definitions(${t} PRIVATE HAVE_STDARG_H=1 HAVE_VSNPRINTF=1)
|
||||
if(MSVC)
|
||||
target_compile_options(${t} PRIVATE -J -W3 ${warn_WX})
|
||||
if(MSVC_FRONTEND)
|
||||
target_compile_options(${t} PRIVATE -W3 ${warn_WX})
|
||||
else()
|
||||
target_compile_definitions(${t} PRIVATE HAVE_UNISTD_H=1)
|
||||
# clang-15: -Wno-strict-prototypes is needed to silence the new -Wdeprecated-non-prototype warning
|
||||
@ -237,8 +242,8 @@ set(t upx_vendor_zstd)
|
||||
upx_compile_target_debug_with_O2(${t})
|
||||
upx_sanitize_target(${t})
|
||||
target_compile_definitions(${t} PRIVATE DYNAMIC_BMI2=0 ZSTD_DISABLE_ASM=1)
|
||||
if(MSVC)
|
||||
target_compile_options(${t} PRIVATE -J ${warn_WN} ${warn_WX})
|
||||
if(MSVC_FRONTEND)
|
||||
target_compile_options(${t} PRIVATE ${warn_WN} ${warn_WX})
|
||||
else()
|
||||
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
|
||||
endif()
|
||||
@ -267,8 +272,8 @@ if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||
endif()
|
||||
#upx_compile_target_debug_with_O2(${t})
|
||||
upx_sanitize_target(${t})
|
||||
if(MSVC)
|
||||
target_compile_options(${t} PRIVATE -EHsc -J ${warn_WN} ${warn_WX})
|
||||
if(MSVC_FRONTEND)
|
||||
target_compile_options(${t} PRIVATE -EHsc ${warn_WN} ${warn_WX})
|
||||
else()
|
||||
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
|
||||
endif()
|
||||
|
||||
@ -165,6 +165,12 @@ template <class T>
|
||||
struct CheckIntegral {
|
||||
template <class U>
|
||||
static void checkU(void) {
|
||||
U a = {};
|
||||
const U b = {};
|
||||
constexpr U c = {};
|
||||
UNUSED(a);
|
||||
UNUSED(b);
|
||||
UNUSED(c);
|
||||
#if __cplusplus < 202002L
|
||||
COMPILE_TIME_ASSERT(std::is_pod<U>::value) // deprecated in C++20
|
||||
#endif
|
||||
@ -217,15 +223,18 @@ struct TestBELE {
|
||||
static noinline bool test(void) {
|
||||
CheckIntegral<T>::check();
|
||||
CheckAlignment<T>::check();
|
||||
// array init
|
||||
T array[2] = {};
|
||||
assert(array[0] == 0 && array[1] == 0);
|
||||
// arithmetic checks (modern compilers will optimize this away)
|
||||
T allbits;
|
||||
allbits = 0;
|
||||
T allbits = {};
|
||||
assert(allbits == 0);
|
||||
allbits += 1;
|
||||
allbits -= 2;
|
||||
T v1;
|
||||
v1 = 1;
|
||||
v1 *= 2;
|
||||
v1 /= 1;
|
||||
v1 *= 4;
|
||||
v1 /= 2;
|
||||
v1 -= 1;
|
||||
T v2;
|
||||
v2 = 1;
|
||||
@ -251,6 +260,8 @@ struct TestBELE {
|
||||
v2 &= v1;
|
||||
v2 /= v1;
|
||||
v2 *= v1;
|
||||
v1 += v2;
|
||||
v1 -= v2;
|
||||
assert(v1 == 1);
|
||||
assert(v2 == 0);
|
||||
if ((v1 ^ v2) != 1)
|
||||
|
||||
14
src/conf.h
14
src/conf.h
@ -65,14 +65,8 @@ ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) == 255) // -funsigned-char
|
||||
// 51:32: error: zero as null pointer constant
|
||||
# pragma GCC diagnostic error "-Wzero-as-null-pointer-constant"
|
||||
#endif
|
||||
#if (ACC_CC_MSC)
|
||||
# pragma warning(error: 4127)
|
||||
# pragma warning(error: 4146)
|
||||
# pragma warning(error: 4319)
|
||||
# pragma warning(error: 4805)
|
||||
#endif
|
||||
#endif // UPX_CONFIG_DISABLE_WSTRICT
|
||||
#endif // UPX_CONFIG_DISABLE_WERROR
|
||||
#endif // UPX_CONFIG_DISABLE_WSTRICT
|
||||
|
||||
// multithreading (UPX currently does not use multithreading)
|
||||
#if (WITH_THREADS)
|
||||
@ -346,7 +340,7 @@ inline void NO_fprintf(FILE *, const char *, ...) {}
|
||||
# define upx_return_address() nullptr
|
||||
#endif
|
||||
|
||||
// TODO cleanup: we now require C++14, so remove all __packed_struct usage
|
||||
// TODO cleanup: we now require C++17, so remove all __packed_struct usage
|
||||
#define __packed_struct(s) struct alignas(1) s {
|
||||
#define __packed_struct_end() };
|
||||
|
||||
@ -774,8 +768,8 @@ class Throwable;
|
||||
|
||||
// util/membuffer.h
|
||||
class MemBuffer;
|
||||
void *membuffer_get_void_ptr(MemBuffer &mb);
|
||||
unsigned membuffer_get_size(MemBuffer &mb);
|
||||
void *membuffer_get_void_ptr(MemBuffer &mb) noexcept;
|
||||
unsigned membuffer_get_size(MemBuffer &mb) noexcept;
|
||||
|
||||
// util/dt_check.cpp
|
||||
void upx_compiler_sanity_check();
|
||||
|
||||
@ -211,6 +211,7 @@ NORET void throwOutOfMemoryException(const char *msg = nullptr);
|
||||
NORET void throwIOException(const char *msg = nullptr, int e = 0);
|
||||
NORET void throwEOFException(const char *msg = nullptr, int e = 0);
|
||||
|
||||
// some C++ template wizardry is needed to overload throwCantPack() for varargs
|
||||
template <class T>
|
||||
void throwCantPack(const T *, ...) = delete;
|
||||
template <>
|
||||
|
||||
@ -28,9 +28,8 @@
|
||||
// main entry, mostly boring stuff; see work.cpp for actual action
|
||||
|
||||
#include "conf.h"
|
||||
#include "file.h"
|
||||
#include "packer.h"
|
||||
#include "p_elf.h"
|
||||
#include "packer.h" // Packer::isValidCompressionMethod()
|
||||
#include "p_elf.h" // ELFOSABI_xxx
|
||||
#include "compress/compress.h" // upx_ucl_init()
|
||||
|
||||
/*************************************************************************
|
||||
|
||||
20
src/packer.h
20
src/packer.h
@ -278,8 +278,16 @@ protected:
|
||||
unsigned image_size, int bits, bool bswap);
|
||||
|
||||
// Target Endianness abstraction
|
||||
#if 1
|
||||
// try to detect TE16 vs TE32 vs TE64 size mismatches; note that "byte" is explicitly allowed
|
||||
#if 0
|
||||
// permissive version using "void *"
|
||||
inline unsigned get_te16(const void *p) const noexcept { return bele->get16(p); }
|
||||
inline unsigned get_te32(const void *p) const noexcept { return bele->get32(p); }
|
||||
inline upx_uint64_t get_te64(const void *p) const noexcept { return bele->get64(p); }
|
||||
inline void set_te16(void *p, unsigned v) noexcept { bele->set16(p, v); }
|
||||
inline void set_te32(void *p, unsigned v) noexcept { bele->set32(p, v); }
|
||||
inline void set_te64(void *p, upx_uint64_t v) noexcept { bele->set64(p, v); }
|
||||
#else
|
||||
// try to detect TE16 vs TE32 vs TE64 size mismatches; note that byte is explicitly allowed
|
||||
template <class T>
|
||||
static inline constexpr bool is_te16_type = is_same_any_v<T, byte, upx_uint16_t, BE16, LE16>;
|
||||
template <class T>
|
||||
@ -312,14 +320,6 @@ protected:
|
||||
inline void set_te64(T *p, upx_uint64_t v) noexcept {
|
||||
bele->set64(p, v);
|
||||
}
|
||||
#else
|
||||
// permissive version using "void *"
|
||||
inline unsigned get_te16(const void *p) const noexcept { return bele->get16(p); }
|
||||
inline unsigned get_te32(const void *p) const noexcept { return bele->get32(p); }
|
||||
inline upx_uint64_t get_te64(const void *p) const noexcept { return bele->get64(p); }
|
||||
inline void set_te16(void *p, unsigned v) noexcept { bele->set16(p, v); }
|
||||
inline void set_te32(void *p, unsigned v) noexcept { bele->set32(p, v); }
|
||||
inline void set_te64(void *p, upx_uint64_t v) noexcept { bele->set64(p, v); }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
@ -29,8 +29,8 @@
|
||||
#include "membuffer.h"
|
||||
|
||||
// extra functions to reduce dependency on membuffer.h
|
||||
void *membuffer_get_void_ptr(MemBuffer &mb) { return mb.getVoidPtr(); }
|
||||
unsigned membuffer_get_size(MemBuffer &mb) { return mb.getSize(); }
|
||||
void *membuffer_get_void_ptr(MemBuffer &mb) noexcept { return mb.getVoidPtr(); }
|
||||
unsigned membuffer_get_size(MemBuffer &mb) noexcept { return mb.getSize(); }
|
||||
|
||||
/*static*/ MemBuffer::Stats MemBuffer::stats;
|
||||
|
||||
@ -45,7 +45,7 @@ unsigned membuffer_get_size(MemBuffer &mb) { return mb.getSize(); }
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(__SANITIZE_ADDRESS__)
|
||||
static forceinline constexpr bool use_simple_mcheck() { return false; }
|
||||
static forceinline constexpr bool use_simple_mcheck() noexcept { return false; }
|
||||
#elif (WITH_VALGRIND) && defined(RUNNING_ON_VALGRIND)
|
||||
static bool use_simple_mcheck_flag;
|
||||
static noinline void init_use_simple_mcheck() noexcept {
|
||||
@ -56,13 +56,13 @@ static noinline void init_use_simple_mcheck() noexcept {
|
||||
}
|
||||
use_simple_mcheck_flag = r;
|
||||
}
|
||||
static bool use_simple_mcheck() {
|
||||
static bool use_simple_mcheck() noexcept {
|
||||
static upx_std_once_flag init_done;
|
||||
upx_std_call_once(init_done, init_use_simple_mcheck);
|
||||
return use_simple_mcheck_flag;
|
||||
}
|
||||
#else
|
||||
static forceinline constexpr bool use_simple_mcheck() { return true; }
|
||||
static forceinline constexpr bool use_simple_mcheck() noexcept { return true; }
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
|
||||
@ -96,11 +96,11 @@ public:
|
||||
|
||||
void dealloc() noexcept;
|
||||
void checkState() const;
|
||||
unsigned getSize() const { return size_in_bytes; }
|
||||
unsigned getSize() const noexcept { return size_in_bytes; }
|
||||
|
||||
// explicit conversion
|
||||
void *getVoidPtr() { return (void *) ptr; }
|
||||
const void *getVoidPtr() const { return (const void *) ptr; }
|
||||
void *getVoidPtr() noexcept { return (void *) ptr; }
|
||||
const void *getVoidPtr() const noexcept { return (const void *) ptr; }
|
||||
|
||||
// util
|
||||
void fill(unsigned off, unsigned len, int value);
|
||||
|
||||
@ -247,20 +247,6 @@ TEST_CASE("ptr_check_no_overlap 3") {
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
/*************************************************************************
|
||||
// bele.h
|
||||
**************************************************************************/
|
||||
|
||||
namespace N_BELE_CTP {
|
||||
const BEPolicy be_policy;
|
||||
const LEPolicy le_policy;
|
||||
} // namespace N_BELE_CTP
|
||||
|
||||
namespace N_BELE_RTP {
|
||||
const BEPolicy be_policy;
|
||||
const LEPolicy le_policy;
|
||||
} // namespace N_BELE_RTP
|
||||
|
||||
/*************************************************************************
|
||||
// stdlib
|
||||
**************************************************************************/
|
||||
@ -312,25 +298,47 @@ TEST_CASE("upx_stable_sort") {
|
||||
CHECK((a[0] == 0 && a[1] == 1));
|
||||
}
|
||||
{
|
||||
LE64 a[3];
|
||||
a[0] = 2;
|
||||
a[1] = 1;
|
||||
a[2] = 0;
|
||||
upx_stable_sort(a, 3, sizeof(*a), le64_compare);
|
||||
CHECK((a[0] == 0 && a[1] == 1 && a[2] == 2));
|
||||
BE64 a[3];
|
||||
a[0] = 257;
|
||||
a[1] = 256;
|
||||
a[2] = 255;
|
||||
upx_stable_sort(a, 3, sizeof(*a), be64_compare);
|
||||
CHECK((a[0] == 255 && a[1] == 256 && a[2] == 257));
|
||||
}
|
||||
#if __cplusplus >= 202002L // use C++20 std::next_permutation() to test all permutations
|
||||
{
|
||||
upx_uint16_t perm[5] = {0, 1, 2, 3, 4}; // 120 permutations
|
||||
do {
|
||||
upx_uint16_t a[5] = {};
|
||||
memcpy(a, perm, sizeof(perm));
|
||||
upx_stable_sort(a, 5, sizeof(*a), ne16_compare);
|
||||
CHECK((a[0] == 0 && a[1] == 1 && a[2] == 2 && a[3] == 3 && a[4] == 4));
|
||||
} while (std::next_permutation(perm, perm + 5));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __cplusplus >= 202002L // use C++20 std::next_permutation() to test all permutations
|
||||
namespace {
|
||||
struct TestSortAllPermutations {
|
||||
static upx_uint64_t test(size_t n) {
|
||||
constexpr size_t N = 16;
|
||||
assert(n > 0 && n <= N);
|
||||
LE16 perm[N];
|
||||
for (size_t i = 0; i < n; i++)
|
||||
perm[i] = 255 + i;
|
||||
upx_uint64_t num_perms = 0;
|
||||
do {
|
||||
LE16 a[N];
|
||||
memcpy(a, perm, sizeof(*a) * n);
|
||||
upx_stable_sort(a, n, sizeof(*a), le16_compare);
|
||||
for (size_t i = 0; i < n; i++)
|
||||
CHECK((a[i] == 255 + i));
|
||||
num_perms += 1;
|
||||
} while (std::next_permutation(perm, perm + n));
|
||||
return num_perms;
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
TEST_CASE("upx_stable_sort") {
|
||||
CHECK(TestSortAllPermutations::test(1) == 1);
|
||||
CHECK(TestSortAllPermutations::test(2) == 2);
|
||||
CHECK(TestSortAllPermutations::test(3) == 6);
|
||||
CHECK(TestSortAllPermutations::test(4) == 24);
|
||||
CHECK(TestSortAllPermutations::test(5) == 120);
|
||||
// CHECK(TestSortAllPermutations::test(6) == 720);
|
||||
// CHECK(TestSortAllPermutations::test(7) == 5040);
|
||||
}
|
||||
#endif // C++20
|
||||
#endif // DEBUG
|
||||
|
||||
/*************************************************************************
|
||||
@ -537,6 +545,20 @@ TEST_CASE("mem_replace") {
|
||||
CHECK(strcmp(b, "cdcdcdcdefgefghh") == 0);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// bele.h globals
|
||||
**************************************************************************/
|
||||
|
||||
namespace N_BELE_CTP {
|
||||
const BEPolicy be_policy;
|
||||
const LEPolicy le_policy;
|
||||
} // namespace N_BELE_CTP
|
||||
|
||||
namespace N_BELE_RTP {
|
||||
const BEPolicy be_policy;
|
||||
const LEPolicy le_policy;
|
||||
} // namespace N_BELE_RTP
|
||||
|
||||
/*************************************************************************
|
||||
// fn - FileName util
|
||||
**************************************************************************/
|
||||
@ -736,7 +758,7 @@ bool makebakname(char *ofilename, size_t size, const char *ifilename, bool force
|
||||
**************************************************************************/
|
||||
|
||||
unsigned get_ratio(upx_uint64_t u_len, upx_uint64_t c_len) {
|
||||
const unsigned n = 1000 * 1000;
|
||||
constexpr unsigned n = 1000 * 1000;
|
||||
if (u_len == 0)
|
||||
return c_len == 0 ? 0 : n;
|
||||
upx_uint64_t x = c_len * n;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user