src: doctest: start work on using doctest
This commit is contained in:
+1
-1
@@ -207,7 +207,7 @@ endif
|
|||||||
# automatically format some C++ source code files
|
# automatically format some C++ source code files
|
||||||
ifeq ($(shell uname),Linux)
|
ifeq ($(shell uname),Linux)
|
||||||
CLANG_FORMAT_FILES += bele.h bele_policy.h
|
CLANG_FORMAT_FILES += bele.h bele_policy.h
|
||||||
CLANG_FORMAT_FILES += except.cpp except.h
|
CLANG_FORMAT_FILES += dt_check.cpp dt_impl.cpp except.cpp except.h
|
||||||
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp packmast.cpp packmast.h
|
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp packmast.cpp packmast.h
|
||||||
CLANG_FORMAT_FILES += main.cpp options.h packer.cpp packer.h
|
CLANG_FORMAT_FILES += main.cpp options.h packer.cpp packer.h
|
||||||
CLANG_FORMAT_FILES += p_tos.cpp p_tos.h
|
CLANG_FORMAT_FILES += p_tos.cpp p_tos.h
|
||||||
|
|||||||
@@ -79,6 +79,11 @@ struct AbstractPolicy {
|
|||||||
S u32_compare_signed(const void *a, const void *b) C = 0;
|
S u32_compare_signed(const void *a, const void *b) C = 0;
|
||||||
S u64_compare_signed(const void *a, const void *b) C = 0;
|
S u64_compare_signed(const void *a, const void *b) C = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// disable copy, assignment and move assignment
|
||||||
|
AbstractPolicy(const AbstractPolicy &) = delete;
|
||||||
|
AbstractPolicy &operator=(const AbstractPolicy &) = delete;
|
||||||
|
AbstractPolicy &operator=(AbstractPolicy &&) = delete;
|
||||||
// disable dynamic allocation
|
// disable dynamic allocation
|
||||||
ACC_CXX_DISABLE_NEW_DELETE
|
ACC_CXX_DISABLE_NEW_DELETE
|
||||||
};
|
};
|
||||||
@@ -141,6 +146,11 @@ struct BEPolicy
|
|||||||
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// disable copy, assignment and move assignment
|
||||||
|
BEPolicy(const BEPolicy &) = delete;
|
||||||
|
BEPolicy &operator=(const BEPolicy &) = delete;
|
||||||
|
BEPolicy &operator=(BEPolicy &&) = delete;
|
||||||
// disable dynamic allocation
|
// disable dynamic allocation
|
||||||
ACC_CXX_DISABLE_NEW_DELETE
|
ACC_CXX_DISABLE_NEW_DELETE
|
||||||
};
|
};
|
||||||
@@ -197,6 +207,11 @@ struct LEPolicy
|
|||||||
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// disable copy, assignment and move assignment
|
||||||
|
LEPolicy(const LEPolicy &) = delete;
|
||||||
|
LEPolicy &operator=(const LEPolicy &) = delete;
|
||||||
|
LEPolicy &operator=(LEPolicy &&) = delete;
|
||||||
// disable dynamic allocation
|
// disable dynamic allocation
|
||||||
ACC_CXX_DISABLE_NEW_DELETE
|
ACC_CXX_DISABLE_NEW_DELETE
|
||||||
};
|
};
|
||||||
|
|||||||
+53
-3
@@ -262,10 +262,8 @@ int upx_ucl_init(void)
|
|||||||
{
|
{
|
||||||
if (ucl_init() != UCL_E_OK)
|
if (ucl_init() != UCL_E_OK)
|
||||||
return -1;
|
return -1;
|
||||||
#if defined(UPX_OFFICIAL_BUILD)
|
if (UCL_VERSION != ucl_version() || strcmp(UCL_VERSION_STRING, ucl_version_string()) != 0)
|
||||||
if (UCL_VERSION != ucl_version())
|
|
||||||
return -2;
|
return -2;
|
||||||
#endif
|
|
||||||
ucl_set_malloc_hooks(my_malloc, my_free);
|
ucl_set_malloc_hooks(my_malloc, my_free);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -287,4 +285,56 @@ unsigned upx_ucl_crc32(const void *buf, unsigned len, unsigned crc)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// Debug checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if DEBUG && 1
|
||||||
|
|
||||||
|
#include "mem.h"
|
||||||
|
|
||||||
|
static bool check_ucl(const int method, const unsigned expected_c_len) {
|
||||||
|
const unsigned u_len = 16384;
|
||||||
|
const unsigned c_extra = 4096;
|
||||||
|
MemBuffer u_buf, c_buf, d_buf;
|
||||||
|
unsigned c_len, d_len;
|
||||||
|
upx_compress_result_t cresult;
|
||||||
|
int r;
|
||||||
|
const int level = 3; // don't waste time
|
||||||
|
|
||||||
|
u_buf.alloc(u_len);
|
||||||
|
memset(u_buf, 0, u_len);
|
||||||
|
c_buf.allocForCompression(u_len, c_extra);
|
||||||
|
d_buf.allocForUncompression(u_len);
|
||||||
|
|
||||||
|
c_len = c_buf.getSize() - c_extra;
|
||||||
|
r = upx_ucl_compress(u_buf, u_len, c_buf + c_extra, &c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||||
|
if (r != 0 || c_len != expected_c_len) return false;
|
||||||
|
|
||||||
|
d_len = d_buf.getSize();
|
||||||
|
r = upx_ucl_decompress(c_buf + c_extra, c_len, d_buf, &d_len, method, nullptr);
|
||||||
|
if (r != 0 || d_len != u_len) return false;
|
||||||
|
if (memcmp(u_buf, d_buf, u_len) != 0) return false;
|
||||||
|
|
||||||
|
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||||
|
//unsigned x_len = d_len;
|
||||||
|
//r = upx_ucl_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("compress_ucl") {
|
||||||
|
CHECK(check_ucl(M_NRV2B_8, 34));
|
||||||
|
CHECK(check_ucl(M_NRV2B_LE16, 34));
|
||||||
|
CHECK(check_ucl(M_NRV2B_LE32, 34));
|
||||||
|
CHECK(check_ucl(M_NRV2D_8, 32));
|
||||||
|
CHECK(check_ucl(M_NRV2D_LE16, 32));
|
||||||
|
CHECK(check_ucl(M_NRV2D_LE32, 34));
|
||||||
|
CHECK(check_ucl(M_NRV2E_8, 32));
|
||||||
|
CHECK(check_ucl(M_NRV2E_LE16, 32));
|
||||||
|
CHECK(check_ucl(M_NRV2E_LE32, 34));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
@@ -217,10 +217,8 @@ int upx_zlib_test_overlap ( const upx_bytep buf,
|
|||||||
|
|
||||||
int upx_zlib_init(void)
|
int upx_zlib_init(void)
|
||||||
{
|
{
|
||||||
#if defined(UPX_OFFICIAL_BUILD)
|
|
||||||
if (strcmp(ZLIB_VERSION, zlibVersion()) != 0)
|
if (strcmp(ZLIB_VERSION, zlibVersion()) != 0)
|
||||||
return -2;
|
return -2;
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+26
-11
@@ -376,6 +376,27 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace compile_time {
|
||||||
|
constexpr bool string_eq(const char *a, const char *b) {
|
||||||
|
return *a == *b && (*a == '\0' || string_eq(a + 1, b + 1));
|
||||||
|
}
|
||||||
|
constexpr bool string_lt(const char *a, const char *b) {
|
||||||
|
return (unsigned char)*a < (unsigned char)*b || (*a != '\0' && *a == *b && string_lt(a + 1, b + 1));
|
||||||
|
}
|
||||||
|
constexpr bool string_ne(const char *a, const char *b) {
|
||||||
|
return !string_eq(a, b);
|
||||||
|
}
|
||||||
|
constexpr bool string_gt(const char *a, const char *b) {
|
||||||
|
return string_lt(b, a);
|
||||||
|
}
|
||||||
|
constexpr bool string_le(const char *a, const char *b) {
|
||||||
|
return !string_lt(b, a);
|
||||||
|
}
|
||||||
|
constexpr bool string_ge(const char *a, const char *b) {
|
||||||
|
return !string_lt(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// constants
|
// constants
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -697,12 +718,6 @@ struct upx_compress_result_t
|
|||||||
#include <new>
|
#include <new>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<short, upx_int16_t>::value))
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned short, upx_uint16_t>::value))
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<int, upx_int32_t>::value))
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned, upx_uint32_t>::value))
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<long long, upx_int64_t>::value))
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned long long, upx_uint64_t>::value))
|
|
||||||
|
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "except.h"
|
#include "except.h"
|
||||||
@@ -710,19 +725,22 @@ ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned long long, upx_uint64_t>::
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
|
||||||
|
//#define DOCTEST_CONFIG_DISABLE
|
||||||
|
#include <doctest/parts/doctest_fwd.h>
|
||||||
|
|
||||||
// classes
|
// classes
|
||||||
class ElfLinker;
|
class ElfLinker;
|
||||||
typedef ElfLinker Linker;
|
typedef ElfLinker Linker;
|
||||||
|
|
||||||
|
// dt_check.cpp
|
||||||
|
void upx_compiler_sanity_check(void);
|
||||||
|
bool upx_doctest_check(void);
|
||||||
|
|
||||||
// main.cpp
|
// main.cpp
|
||||||
extern const char *progname;
|
extern const char *progname;
|
||||||
bool set_exit_code(int ec);
|
bool set_exit_code(int ec);
|
||||||
void upx_compiler_sanity_check(void);
|
|
||||||
int upx_main(int argc, char *argv[]);
|
int upx_main(int argc, char *argv[]);
|
||||||
|
|
||||||
|
|
||||||
// msg.cpp
|
// msg.cpp
|
||||||
void printSetNl(int need_nl);
|
void printSetNl(int need_nl);
|
||||||
void printClearLine(FILE *f = nullptr);
|
void printClearLine(FILE *f = nullptr);
|
||||||
@@ -737,12 +755,10 @@ void info(const char *format, ...) attribute_format(1, 2);
|
|||||||
void infoHeader(void);
|
void infoHeader(void);
|
||||||
void infoWriting(const char *what, long size);
|
void infoWriting(const char *what, long size);
|
||||||
|
|
||||||
|
|
||||||
// work.cpp
|
// work.cpp
|
||||||
void do_one_file(const char *iname, char *oname);
|
void do_one_file(const char *iname, char *oname);
|
||||||
int do_files(int i, int argc, char *argv[]);
|
int do_files(int i, int argc, char *argv[]);
|
||||||
|
|
||||||
|
|
||||||
// help.cpp
|
// help.cpp
|
||||||
extern const char gitrev[];
|
extern const char gitrev[];
|
||||||
void show_head(void);
|
void show_head(void);
|
||||||
@@ -751,7 +767,6 @@ void show_license(void);
|
|||||||
void show_usage(void);
|
void show_usage(void);
|
||||||
void show_version(int);
|
void show_version(int);
|
||||||
|
|
||||||
|
|
||||||
// compress.cpp
|
// compress.cpp
|
||||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
|
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
|
||||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc=0);
|
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc=0);
|
||||||
|
|||||||
@@ -0,0 +1,400 @@
|
|||||||
|
/* dt_check.cpp -- doctest check
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2022 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
|
||||||
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "conf.h"
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// upx_doctest_check()
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
bool upx_doctest_check(void) {
|
||||||
|
bool minimal = true; // only show failing tests
|
||||||
|
bool duration = false; // show timings
|
||||||
|
const char *e = getenv("UPX_DEBUG_DOCTEST_VERBOSE");
|
||||||
|
if (e && e[0] && strcmp(e, "0") != 0) {
|
||||||
|
minimal = false;
|
||||||
|
if (strcmp(e, "2") == 0)
|
||||||
|
duration = true;
|
||||||
|
}
|
||||||
|
#if DEBUG
|
||||||
|
minimal = false;
|
||||||
|
// duration = true;
|
||||||
|
#endif
|
||||||
|
doctest::Context context;
|
||||||
|
if (minimal)
|
||||||
|
context.setOption("dt-minimal", true);
|
||||||
|
if (duration)
|
||||||
|
context.setOption("dt-duration", true);
|
||||||
|
int r = context.run();
|
||||||
|
if (context.shouldExit() || r != 0)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// compile-time checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<short, upx_int16_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned short, upx_uint16_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<int, upx_int32_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned, upx_uint32_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<long long, upx_int64_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned long long, upx_uint64_t>::value))
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap16(0x04030201) == 0x0201)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap32(0x04030201) == 0x04030201)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap64(0x0807060504030201ull) == 0x0807060504030201ull)
|
||||||
|
#if !(ACC_CC_MSC)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap16(0x04030201) == 0x0102)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap32(0x04030201) == 0x01020304)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap64(0x0807060504030201ull) == 0x0102030405060708ull)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("", ""))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("a", ""))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("", "a"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("abc", "abc"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("ab", "abc"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("abc", "ab"))
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("", ""))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("a", ""))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("", "a"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "abc"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("ab", "abc"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "ab"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "aba"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("abc", "abz"))
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_ne("abc", "abz"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_gt("abc", "abz"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_ge("abc", "abz"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_le("abc", "abz"))
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// upx_compiler_sanity_check()
|
||||||
|
// assert a sane architecture and compiler
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct TestBELE {
|
||||||
|
__acc_static_noinline bool test(void) {
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(T)
|
||||||
|
struct alignas(1) test1_t {
|
||||||
|
char a;
|
||||||
|
T b;
|
||||||
|
};
|
||||||
|
struct alignas(1) test2_t {
|
||||||
|
char a;
|
||||||
|
T b[3];
|
||||||
|
};
|
||||||
|
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
|
||||||
|
T allbits;
|
||||||
|
allbits = 0;
|
||||||
|
allbits += 1;
|
||||||
|
allbits -= 2;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class A, class B>
|
||||||
|
struct TestNoAliasingStruct {
|
||||||
|
__acc_static_noinline bool test(A *a, B *b) {
|
||||||
|
*a = 0;
|
||||||
|
*b = 0;
|
||||||
|
*b -= 3;
|
||||||
|
return *a != 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <class A, class B>
|
||||||
|
__acc_static_forceinline bool testNoAliasing(A *a, B *b) {
|
||||||
|
return TestNoAliasingStruct<A, B>::test(a, b);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
struct TestIntegerWrap {
|
||||||
|
static inline bool inc(T x) { return x + 1 > x; }
|
||||||
|
static inline bool dec(T x) { return x - 1 < x; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#define ACC_WANT_ACC_CHK_CH 1
|
||||||
|
#undef ACCCHK_ASSERT
|
||||||
|
#include "miniacc.h"
|
||||||
|
|
||||||
|
void upx_compiler_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(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);
|
||||||
|
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] == '+');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(UPX_RSIZE_MAX_MEM == 805306368);
|
||||||
|
|
||||||
|
#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());
|
||||||
|
{
|
||||||
|
alignas(16) static const unsigned char dd[32] = {
|
||||||
|
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) == -506097522914230529LL);
|
||||||
|
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) == 9186918263483431288LL);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
unsigned dd;
|
||||||
|
void *const d = ⅆ
|
||||||
|
dd = ne32_to_le32(0xf7f6f5f4);
|
||||||
|
assert(get_le26(d) == 0x03f6f5f4);
|
||||||
|
set_le26(d, 0);
|
||||||
|
assert(get_le26(d) == 0);
|
||||||
|
assert(dd == ne32_to_le32(0xf4000000));
|
||||||
|
set_le26(d, 0xff020304);
|
||||||
|
assert(get_le26(d) == 0x03020304);
|
||||||
|
assert(dd == ne32_to_le32(0xf7020304));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
union {
|
||||||
|
short v_short;
|
||||||
|
int v_int;
|
||||||
|
long v_long;
|
||||||
|
long long v_llong;
|
||||||
|
BE16 b16;
|
||||||
|
BE32 b32;
|
||||||
|
BE64 b64;
|
||||||
|
LE16 l16;
|
||||||
|
LE32 l32;
|
||||||
|
LE64 l64;
|
||||||
|
} u;
|
||||||
|
assert(testNoAliasing(&u.v_short, &u.b32));
|
||||||
|
assert(testNoAliasing(&u.v_short, &u.l32));
|
||||||
|
assert(testNoAliasing(&u.v_int, &u.b64));
|
||||||
|
assert(testNoAliasing(&u.v_int, &u.l64));
|
||||||
|
// check working -fno-strict-aliasing
|
||||||
|
assert(testNoAliasing(&u.v_short, &u.v_int));
|
||||||
|
assert(testNoAliasing(&u.v_int, &u.v_long));
|
||||||
|
assert(testNoAliasing(&u.v_int, &u.v_llong));
|
||||||
|
assert(testNoAliasing(&u.v_long, &u.v_llong));
|
||||||
|
|
||||||
|
assert(TestIntegerWrap<unsigned>::inc(0));
|
||||||
|
assert(!TestIntegerWrap<unsigned>::inc(UINT_MAX));
|
||||||
|
assert(TestIntegerWrap<unsigned>::dec(1));
|
||||||
|
assert(!TestIntegerWrap<unsigned>::dec(0));
|
||||||
|
// check working -fno-strict-overflow
|
||||||
|
assert(TestIntegerWrap<int>::inc(0));
|
||||||
|
assert(!TestIntegerWrap<int>::inc(INT_MAX));
|
||||||
|
assert(TestIntegerWrap<int>::dec(0));
|
||||||
|
assert(!TestIntegerWrap<int>::dec(INT_MIN));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// some doctest test cases
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("acc_vget") {
|
||||||
|
CHECK_EQ(acc_vget_int(0, 0), 0);
|
||||||
|
CHECK_EQ(acc_vget_long(1, -1), 1);
|
||||||
|
CHECK_EQ(acc_vget_acc_int64l_t(2, 1), 2);
|
||||||
|
CHECK_EQ(acc_vget_acc_hvoid_p(nullptr, 0), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("working -fno-strict-aliasing") {
|
||||||
|
bool ok;
|
||||||
|
long v = 0;
|
||||||
|
short *ps = ACC_STATIC_CAST(short *, acc_vget_acc_hvoid_p(&v, 0));
|
||||||
|
int *pi = ACC_STATIC_CAST(int *, acc_vget_acc_hvoid_p(&v, 0));
|
||||||
|
long *pl = ACC_STATIC_CAST(long *, acc_vget_acc_hvoid_p(&v, 0));
|
||||||
|
*ps = 0;
|
||||||
|
*pl = -1;
|
||||||
|
ok = *ps == -1;
|
||||||
|
CHECK(ok);
|
||||||
|
*pi = 0;
|
||||||
|
*pl = -1;
|
||||||
|
ok = *pi == -1;
|
||||||
|
CHECK(ok);
|
||||||
|
*pl = 0;
|
||||||
|
*ps = -1;
|
||||||
|
ok = *pl != 0;
|
||||||
|
CHECK(ok);
|
||||||
|
*pl = 0;
|
||||||
|
*pi = -1;
|
||||||
|
ok = *pl != 0;
|
||||||
|
CHECK(ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("working -fno-strict-overflow") {
|
||||||
|
CHECK_EQ(acc_vget_int(INT_MAX, 0) + 1, INT_MIN);
|
||||||
|
CHECK_EQ(acc_vget_int(INT_MIN, 0) - 1, INT_MAX);
|
||||||
|
CHECK_EQ(acc_vget_long(LONG_MAX, 0) + 1, LONG_MIN);
|
||||||
|
CHECK_EQ(acc_vget_long(LONG_MIN, 0) - 1, LONG_MAX);
|
||||||
|
bool ok;
|
||||||
|
int i;
|
||||||
|
i = INT_MAX;
|
||||||
|
i += 1;
|
||||||
|
ok = i == INT_MIN;
|
||||||
|
CHECK(ok);
|
||||||
|
i = INT_MIN;
|
||||||
|
i -= 1;
|
||||||
|
ok = i == INT_MAX;
|
||||||
|
CHECK(ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("libc snprintf") {
|
||||||
|
// runtime check that Win32/MinGW <stdio.h> works as expected
|
||||||
|
long long ll = acc_vget_int(-1, 0);
|
||||||
|
unsigned long long llu = (unsigned long long) ll;
|
||||||
|
char buf[64];
|
||||||
|
snprintf(buf, sizeof(buf), ".%d.%ld.%lld.%u.%lu.%llu", -3, -2L, ll, 3U, 2LU, llu);
|
||||||
|
CHECK_EQ(strcmp(buf, ".-3.-2.-1.3.2.18446744073709551615"), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/* dt_impl.cpp -- doctest support code implementation
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2022 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
|
||||||
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// doctest support code implementation
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#define DOCTEST_CONFIG_IMPLEMENT
|
||||||
|
#define DOCTEST_CONFIG_NO_MULTITHREADING
|
||||||
|
#define DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
|
||||||
|
#include <doctest/parts/doctest.cpp>
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
+10
-260
@@ -926,8 +926,6 @@ static int get_options(int argc, char **argv) {
|
|||||||
{"crp-zlib-ml", 0x31, N, 821},
|
{"crp-zlib-ml", 0x31, N, 821},
|
||||||
{"crp-zlib-wb", 0x31, N, 822},
|
{"crp-zlib-wb", 0x31, N, 822},
|
||||||
{"crp-zlib-st", 0x31, N, 823},
|
{"crp-zlib-st", 0x31, N, 823},
|
||||||
// [deprecated - only for compatibility with UPX 2.0x]
|
|
||||||
{"crp-ms", 0x31, N, 807},
|
|
||||||
|
|
||||||
// atari/tos
|
// atari/tos
|
||||||
{"split-segments", 0x10, N, 650},
|
{"split-segments", 0x10, N, 650},
|
||||||
@@ -1164,242 +1162,6 @@ static void first_options(int argc, char **argv) {
|
|||||||
do_option(519, argv[i]);
|
do_option(519, argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// assert a sane architecture and compiler
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct TestBELE {
|
|
||||||
__acc_static_noinline bool test(void) {
|
|
||||||
COMPILE_TIME_ASSERT_ALIGNED1(T)
|
|
||||||
struct alignas(1) test1_t {
|
|
||||||
char a;
|
|
||||||
T b;
|
|
||||||
};
|
|
||||||
struct alignas(1) test2_t {
|
|
||||||
char a;
|
|
||||||
T b[3];
|
|
||||||
};
|
|
||||||
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
|
|
||||||
T allbits;
|
|
||||||
allbits = 0;
|
|
||||||
allbits += 1;
|
|
||||||
allbits -= 2;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class A, class B>
|
|
||||||
struct TestNoAliasingStruct {
|
|
||||||
__acc_static_noinline bool test(A *a, B *b) {
|
|
||||||
*a = 0;
|
|
||||||
*b = 0;
|
|
||||||
*b -= 3;
|
|
||||||
return *a != 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template <class A, class B>
|
|
||||||
__acc_static_forceinline bool testNoAliasing(A *a, B *b) {
|
|
||||||
return TestNoAliasingStruct<A, B>::test(a, b);
|
|
||||||
}
|
|
||||||
template <class T>
|
|
||||||
struct TestIntegerWrap {
|
|
||||||
static inline bool inc(T x) { return x + 1 > x; }
|
|
||||||
static inline bool dec(T x) { return x - 1 < x; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ACC_WANT_ACC_CHK_CH 1
|
|
||||||
#undef ACCCHK_ASSERT
|
|
||||||
#include "miniacc.h"
|
|
||||||
|
|
||||||
void upx_compiler_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(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);
|
|
||||||
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] == '+');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(UPX_RSIZE_MAX_MEM == 805306368);
|
|
||||||
|
|
||||||
#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());
|
|
||||||
{
|
|
||||||
alignas(16) static const unsigned char dd[32] = {
|
|
||||||
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) == -506097522914230529LL);
|
|
||||||
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) == 9186918263483431288LL);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
unsigned dd;
|
|
||||||
void *const d = ⅆ
|
|
||||||
dd = ne32_to_le32(0xf7f6f5f4);
|
|
||||||
assert(get_le26(d) == 0x03f6f5f4);
|
|
||||||
set_le26(d, 0);
|
|
||||||
assert(get_le26(d) == 0);
|
|
||||||
assert(dd == ne32_to_le32(0xf4000000));
|
|
||||||
set_le26(d, 0xff020304);
|
|
||||||
assert(get_le26(d) == 0x03020304);
|
|
||||||
assert(dd == ne32_to_le32(0xf7020304));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
union {
|
|
||||||
short v_short;
|
|
||||||
int v_int;
|
|
||||||
long v_long;
|
|
||||||
long long v_llong;
|
|
||||||
BE16 b16;
|
|
||||||
BE32 b32;
|
|
||||||
BE64 b64;
|
|
||||||
LE16 l16;
|
|
||||||
LE32 l32;
|
|
||||||
LE64 l64;
|
|
||||||
} u;
|
|
||||||
assert(testNoAliasing(&u.v_short, &u.b32));
|
|
||||||
assert(testNoAliasing(&u.v_short, &u.l32));
|
|
||||||
assert(testNoAliasing(&u.v_int, &u.b64));
|
|
||||||
assert(testNoAliasing(&u.v_int, &u.l64));
|
|
||||||
#if 1
|
|
||||||
// check working -fno-strict-aliasing
|
|
||||||
assert(testNoAliasing(&u.v_short, &u.v_int));
|
|
||||||
assert(testNoAliasing(&u.v_int, &u.v_long));
|
|
||||||
assert(testNoAliasing(&u.v_int, &u.v_llong));
|
|
||||||
assert(testNoAliasing(&u.v_long, &u.v_llong));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
assert(TestIntegerWrap<int>::inc(0));
|
|
||||||
assert(!TestIntegerWrap<int>::inc(INT_MAX));
|
|
||||||
assert(TestIntegerWrap<int>::dec(0));
|
|
||||||
assert(!TestIntegerWrap<int>::dec(INT_MIN));
|
|
||||||
assert(TestIntegerWrap<unsigned>::inc(0));
|
|
||||||
assert(!TestIntegerWrap<unsigned>::inc(UINT_MAX));
|
|
||||||
assert(TestIntegerWrap<unsigned>::dec(1));
|
|
||||||
assert(!TestIntegerWrap<unsigned>::dec(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// main entry point
|
// main entry point
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -1407,15 +1169,21 @@ void upx_compiler_sanity_check(void) {
|
|||||||
int upx_main(int argc, char *argv[]) {
|
int upx_main(int argc, char *argv[]) {
|
||||||
int i;
|
int i;
|
||||||
static char default_argv0[] = "upx";
|
static char default_argv0[] = "upx";
|
||||||
|
assert(argc >= 1); // sanity check
|
||||||
|
if (!argv[0] || !argv[0][0])
|
||||||
|
argv[0] = default_argv0;
|
||||||
|
argv0 = argv[0];
|
||||||
|
|
||||||
upx_compiler_sanity_check();
|
upx_compiler_sanity_check();
|
||||||
|
if (!upx_doctest_check()) {
|
||||||
|
fprintf(stderr, "%s: internal error: doctest failed\n", argv0);
|
||||||
|
e_exit(EXIT_INIT);
|
||||||
|
}
|
||||||
|
|
||||||
// Allow serial re-use of upx_main() as a subroutine
|
// Allow serial re-use of upx_main() as a subroutine
|
||||||
done_output_name = 0;
|
done_output_name = 0;
|
||||||
opt->reset();
|
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 || \
|
#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)
|
ACC_OS_WIN32 || ACC_OS_WIN64)
|
||||||
{
|
{
|
||||||
@@ -1442,15 +1210,8 @@ int upx_main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
set_term(stderr);
|
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_lzma_init() == 0);
|
||||||
|
assert(upx_ucl_init() == 0);
|
||||||
assert(upx_zlib_init() == 0);
|
assert(upx_zlib_init() == 0);
|
||||||
#if (WITH_NRV)
|
#if (WITH_NRV)
|
||||||
assert(upx_nrv_init() == 0);
|
assert(upx_nrv_init() == 0);
|
||||||
@@ -1570,17 +1331,6 @@ int __acc_cdecl_main main(int argc, char *argv[]) {
|
|||||||
// srand((int) time(nullptr));
|
// srand((int) time(nullptr));
|
||||||
srand((int) clock());
|
srand((int) clock());
|
||||||
|
|
||||||
#if defined(_WIN32) || 1
|
|
||||||
// runtime check that Win32/MinGW <stdio.h> works as expected
|
|
||||||
{
|
|
||||||
long long ll = argc < 0 ? 0 : -1;
|
|
||||||
unsigned long long llu = (unsigned long long) ll;
|
|
||||||
char buf[256];
|
|
||||||
snprintf(buf, sizeof(buf), ".%d.%ld.%lld.%u.%lu.%llu", -3, -2L, ll, 3U, 2LU, llu);
|
|
||||||
assert(strcmp(buf, ".-3.-2.-1.3.2.18446744073709551615") == 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int r = upx_main(argc, argv);
|
int r = upx_main(argc, argv);
|
||||||
|
|
||||||
#if 0 && defined(__GLIBC__)
|
#if 0 && defined(__GLIBC__)
|
||||||
|
|||||||
+1
-1
@@ -53,7 +53,7 @@ __acc_static_forceinline bool use_simple_mcheck()
|
|||||||
return (bool) use_simple_mcheck_flag;
|
return (bool) use_simple_mcheck_flag;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
__acc_static_forceinline bool use_simple_mcheck() { return true; }
|
__acc_static_forceinline constexpr bool use_simple_mcheck() { return true; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -75,10 +75,10 @@ private:
|
|||||||
|
|
||||||
static unsigned global_alloc_counter;
|
static unsigned global_alloc_counter;
|
||||||
|
|
||||||
// disable copy and assignment
|
// disable copy, assignment and move assignment
|
||||||
MemBuffer(const MemBuffer &) = delete;
|
MemBuffer(const MemBuffer &) = delete;
|
||||||
MemBuffer& operator= (const MemBuffer &) = delete;
|
MemBuffer& operator= (const MemBuffer &) = delete;
|
||||||
|
MemBuffer& operator= (MemBuffer &&) = delete;
|
||||||
// disable dynamic allocation
|
// disable dynamic allocation
|
||||||
ACC_CXX_DISABLE_NEW_DELETE
|
ACC_CXX_DISABLE_NEW_DELETE
|
||||||
};
|
};
|
||||||
|
|||||||
+8
-4
@@ -1674,7 +1674,11 @@ extern "C" {
|
|||||||
# define __acc_forceinline __acc_inline
|
# define __acc_forceinline __acc_inline
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_noinline)
|
#if !defined(__acc_noinline)
|
||||||
#if 1 && (ACC_ARCH_I386) && (ACC_CC_GNUC >= 0x040000ul) && (ACC_CC_GNUC < 0x040003ul)
|
#if (ACC_CC_GNUC >= 0x080000ul)
|
||||||
|
# define __acc_noinline __attribute__((__noinline__,__noipa__))
|
||||||
|
#elif (ACC_CC_GNUC >= 0x050000ul)
|
||||||
|
# define __acc_noinline __attribute__((__noinline__,__noclone__,__no_icf__))
|
||||||
|
#elif 1 && (ACC_ARCH_I386) && (ACC_CC_GNUC >= 0x040000ul) && (ACC_CC_GNUC < 0x040003ul)
|
||||||
# define __acc_noinline __attribute__((__noinline__,__used__))
|
# define __acc_noinline __attribute__((__noinline__,__used__))
|
||||||
#elif (ACC_CC_GNUC >= 0x030200ul)
|
#elif (ACC_CC_GNUC >= 0x030200ul)
|
||||||
# define __acc_noinline __attribute__((__noinline__))
|
# define __acc_noinline __attribute__((__noinline__))
|
||||||
@@ -6316,13 +6320,13 @@ ACCLIB_PUBLIC(void, acc_ua_set_le64) (acc_hvoid_p p, acc_uint64l_t v)
|
|||||||
#endif
|
#endif
|
||||||
extern void* volatile acc_vget_ptr__;
|
extern void* volatile acc_vget_ptr__;
|
||||||
#if (ACC_CC_CLANG || (ACC_CC_GNUC >= 0x030400ul) || ACC_CC_LLVM)
|
#if (ACC_CC_CLANG || (ACC_CC_GNUC >= 0x030400ul) || ACC_CC_LLVM)
|
||||||
void* volatile __attribute__((__used__)) acc_vget_ptr__ = ACC_STATIC_CAST(void *, 0);
|
void* volatile __attribute__((__used__)) acc_vget_ptr__ = ACC_STATIC_CAST(void *, nullptr);
|
||||||
#else
|
#else
|
||||||
void* volatile acc_vget_ptr__ = ACC_STATIC_CAST(void *, 0);
|
void* volatile acc_vget_ptr__ = ACC_STATIC_CAST(void *, nullptr);
|
||||||
#endif
|
#endif
|
||||||
#ifndef __ACCLIB_VGET_BODY
|
#ifndef __ACCLIB_VGET_BODY
|
||||||
#define __ACCLIB_VGET_BODY(T) \
|
#define __ACCLIB_VGET_BODY(T) \
|
||||||
if __acc_unlikely(acc_vget_ptr__) { \
|
if __acc_very_unlikely(acc_vget_ptr__) { \
|
||||||
typedef T __acc_may_alias TT; \
|
typedef T __acc_may_alias TT; \
|
||||||
unsigned char e; expr &= 255; e = ACC_STATIC_CAST(unsigned char, expr); \
|
unsigned char e; expr &= 255; e = ACC_STATIC_CAST(unsigned char, expr); \
|
||||||
* ACC_STATIC_CAST(TT *, acc_vget_ptr__) = v; \
|
* ACC_STATIC_CAST(TT *, acc_vget_ptr__) = v; \
|
||||||
|
|||||||
+6
-5
@@ -1434,8 +1434,9 @@ void Packer::compressWithFilters(upx_bytep i_ptr,
|
|||||||
void Packer::compressWithFilters(Filter *ft, const unsigned overlap_range,
|
void Packer::compressWithFilters(Filter *ft, const unsigned overlap_range,
|
||||||
const upx_compress_config_t *cconf, int filter_strategy,
|
const upx_compress_config_t *cconf, int filter_strategy,
|
||||||
bool inhibit_compression_check) {
|
bool inhibit_compression_check) {
|
||||||
compressWithFilters( // call the subroutine immediately below
|
// call the subroutine immediately below
|
||||||
ft, overlap_range, cconf, filter_strategy, 0, 0, 0, nullptr, 0, inhibit_compression_check);
|
compressWithFilters(ft, overlap_range, cconf, filter_strategy, 0, 0, 0, nullptr, 0,
|
||||||
|
inhibit_compression_check);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packer::compressWithFilters(Filter *ft, const unsigned overlap_range,
|
void Packer::compressWithFilters(Filter *ft, const unsigned overlap_range,
|
||||||
@@ -1454,9 +1455,9 @@ void Packer::compressWithFilters(Filter *ft, const unsigned overlap_range,
|
|||||||
|
|
||||||
assert(f_ptr + f_len <= i_ptr + i_len);
|
assert(f_ptr + f_len <= i_ptr + i_len);
|
||||||
|
|
||||||
compressWithFilters( // call the first one in this file
|
// call the first one in this file
|
||||||
i_ptr, i_len, o_ptr, f_ptr, f_len, hdr_ptr, hdr_len, ft, overlap_range, cconf,
|
compressWithFilters(i_ptr, i_len, o_ptr, f_ptr, f_len, hdr_ptr, hdr_len, ft, overlap_range,
|
||||||
filter_strategy, inhibit_compression_check);
|
cconf, filter_strategy, inhibit_compression_check);
|
||||||
|
|
||||||
ibuf.checkState();
|
ibuf.checkState();
|
||||||
obuf.checkState();
|
obuf.checkState();
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#define ACC_WANT_ACCLIB_GETOPT 1
|
#define ACC_WANT_ACCLIB_GETOPT 1
|
||||||
#define ACC_WANT_ACCLIB_HSREAD 1
|
#define ACC_WANT_ACCLIB_HSREAD 1
|
||||||
#define ACC_WANT_ACCLIB_MISC 1
|
#define ACC_WANT_ACCLIB_MISC 1
|
||||||
|
#define ACC_WANT_ACCLIB_VGET 1
|
||||||
#define ACC_WANT_ACCLIB_WILDARGV 1
|
#define ACC_WANT_ACCLIB_WILDARGV 1
|
||||||
#undef HAVE_MKDIR
|
#undef HAVE_MKDIR
|
||||||
#include "miniacc.h"
|
#include "miniacc.h"
|
||||||
@@ -92,6 +93,15 @@ bool mem_size_valid_bytes(upx_uint64_t bytes) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("mem_size") {
|
||||||
|
CHECK(mem_size_valid(1, 0));
|
||||||
|
CHECK(mem_size_valid(1, 0x30000000));
|
||||||
|
CHECK(!mem_size_valid(1, 0x30000000 + 1));
|
||||||
|
CHECK(!mem_size_valid(1, 0x30000000, 1));
|
||||||
|
CHECK(!mem_size_valid(1, 0x30000000, 0, 1));
|
||||||
|
CHECK(!mem_size_valid(1, 0x30000000, 0x30000000, 0x30000000));
|
||||||
|
}
|
||||||
|
|
||||||
int ptr_diff(const void *p1, const void *p2) {
|
int ptr_diff(const void *p1, const void *p2) {
|
||||||
assert(p1 != nullptr);
|
assert(p1 != nullptr);
|
||||||
assert(p2 != nullptr);
|
assert(p2 != nullptr);
|
||||||
@@ -284,6 +294,24 @@ int find_le64(const void *b, int blen, upx_uint64_t what) {
|
|||||||
return find(b, blen, w, 8);
|
return find(b, blen, w, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("find") {
|
||||||
|
static const unsigned char b[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
||||||
|
CHECK(find(b, 16, b, 0) == -1);
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
CHECK(find(b, 16, b + i, 1) == i);
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= 16; i++) {
|
||||||
|
CHECK(find(b, 16, b, i) == 0);
|
||||||
|
}
|
||||||
|
CHECK(find(b, 16, b, 17) == -1);
|
||||||
|
CHECK(find_be16(b, 16, 0x0203) == 2);
|
||||||
|
CHECK(find_le16(b, 16, 0x0302) == 2);
|
||||||
|
CHECK(find_be32(b, 16, 0x04050607) == 4);
|
||||||
|
CHECK(find_le32(b, 16, 0x07060504) == 4);
|
||||||
|
CHECK(find_be64(b, 16, 0x08090a0b0c0d0e0fULL) == 8);
|
||||||
|
CHECK(find_le64(b, 16, 0x0f0e0d0c0b0a0908ULL) == 8);
|
||||||
|
}
|
||||||
|
|
||||||
int mem_replace(void *bb, int blen, const void *what, int wlen, const void *r) {
|
int mem_replace(void *bb, int blen, const void *what, int wlen, const void *r) {
|
||||||
unsigned char *b = (unsigned char *) bb;
|
unsigned char *b = (unsigned char *) bb;
|
||||||
int boff = 0;
|
int boff = 0;
|
||||||
@@ -301,6 +329,16 @@ int mem_replace(void *bb, int blen, const void *what, int wlen, const void *r) {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("mem_replace") {
|
||||||
|
char b[16 + 1] = "aaaaaaaaaaaaaaaa";
|
||||||
|
CHECK(mem_replace(b, 16, "a", 0, "x") == 0);
|
||||||
|
CHECK(mem_replace(b, 16, "a", 1, "b") == 16);
|
||||||
|
CHECK(mem_replace(b, 8, "bb", 2, "cd") == 4);
|
||||||
|
CHECK(mem_replace(b + 8, 8, "bbb", 3, "efg") == 2);
|
||||||
|
CHECK(mem_replace(b, 16, "b", 1, "h") == 2);
|
||||||
|
CHECK(strcmp(b, "cdcdcdcdefgefghh") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// fn - FileName util
|
// fn - FileName util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -512,4 +550,16 @@ unsigned get_ratio(upx_uint64_t u_len, upx_uint64_t c_len) {
|
|||||||
return ACC_ICONV(unsigned, x);
|
return ACC_ICONV(unsigned, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("get_ratio") {
|
||||||
|
CHECK(get_ratio(0, 0) == 0);
|
||||||
|
CHECK(get_ratio(0, 1) == 1000000);
|
||||||
|
CHECK(get_ratio(1, 0) == 50);
|
||||||
|
CHECK(get_ratio(1, 1) == 1000050);
|
||||||
|
CHECK(get_ratio(1, 9) == 9000050);
|
||||||
|
CHECK(get_ratio(1, 10) == 9999999);
|
||||||
|
CHECK(get_ratio(1, 11) == 9999999);
|
||||||
|
CHECK(get_ratio(100000, 100000) == 1000050);
|
||||||
|
CHECK(get_ratio(100000, 200000) == 2000050);
|
||||||
|
}
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
Reference in New Issue
Block a user