mirror of
https://github.com/upx/upx.git
synced 2024-11-23 04:39:59 +00:00
CI updates and minor cleanups
This commit is contained in:
parent
70b20d7d89
commit
24f3824524
4
.gitattributes
vendored
4
.gitattributes
vendored
@ -3,6 +3,10 @@
|
||||
#
|
||||
# HINT: check settings with
|
||||
# git ls-files | git check-attr --stdin --all
|
||||
# git ls-files --eol
|
||||
|
||||
# disable all line ending conversions
|
||||
* -text
|
||||
|
||||
#
|
||||
# tell diff tools that these files are generated automatically
|
||||
|
17
.github/workflows/ci.yml
vendored
17
.github/workflows/ci.yml
vendored
@ -16,8 +16,9 @@ env:
|
||||
UPX_CMAKE_BUILD_FLAGS: --verbose
|
||||
UPX_CMAKE_CONFIG_FLAGS: -Wdev --warn-uninitialized
|
||||
UPX_DEBUG_TEST_FLOAT_DIVISION_BY_ZERO: 1
|
||||
# 2024-03-29
|
||||
ZIG_DIST_VERSION: 0.12.0-dev.3484+7aa42f47b
|
||||
UPX_DEBUG_TEST_LIBC_QSORT: 1
|
||||
# 2024-04-01
|
||||
ZIG_DIST_VERSION: 0.12.0-dev.3508+a6ed3e6d2
|
||||
|
||||
jobs:
|
||||
job-rebuild-and-verify-stubs:
|
||||
@ -183,7 +184,7 @@ jobs:
|
||||
job-macos-cmake: # uses cmake + make
|
||||
if: true
|
||||
needs: [ job-rebuild-and-verify-stubs ]
|
||||
name: ${{ format('{0} {1}', matrix.os, matrix.xcode_version) }}
|
||||
name: ${{ format('{0} {1}{2}', matrix.os, matrix.xcode_version && 'xcode-' || '', matrix.xcode_version) }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@ -193,8 +194,8 @@ jobs:
|
||||
# NOTE: macos-11 does not have "readlink -f"; only on macos >= 12 or with brew coreutils
|
||||
- { os: macos-11, gcc: gcc-10, gxx: 'g++-10', testsuite: true }
|
||||
- { os: macos-12, gcc: gcc-11, gxx: 'g++-11', testsuite: true }
|
||||
- { os: macos-13, gcc: gcc-12, gxx: 'g++-12', testsuite: true, xcode_version: 14.3.1 }
|
||||
- { os: macos-13, testsuite: true } # use default Xcode-15
|
||||
- { os: macos-13, gcc: gcc-12, gxx: 'g++-12', testsuite: true, xcode_version: 14.3.1 }
|
||||
# { os: macos-14, gcc: gcc-13, gxx: 'g++-13', testsuite: true } # gcc-13: INTERNAL ERROR in ld64
|
||||
# { os: macos-14, gcc: gcc-13, gxx: 'g++-13', testsuite: true, xcode_version: 14.3.1 } # gcc-13: MISSING HEADER FILES
|
||||
- { os: macos-14, gcc: gcc-12, gxx: 'g++-12', testsuite: true } # => use gcc-12 for now
|
||||
@ -465,16 +466,18 @@ jobs:
|
||||
- { zig_target: aarch64-windows-gnu }
|
||||
- { zig_target: arm-linux-musleabihf, qemu: qemu-arm }
|
||||
# { zig_target: arm-linux-musleabihf, qemu: qemu-arm, zig_pic: -fPIE }
|
||||
- { zig_target: i386-linux-musl, qemu: qemu-i386 }
|
||||
# { zig_target: i386-linux-musl, qemu: qemu-i386, zig_pic: -fPIE }
|
||||
- { zig_target: i386-linux-gnu.2.3.4, zig_flags: -march=i586 }
|
||||
- { zig_target: i386-linux-musl, zig_flags: -march=i586, qemu: qemu-i386 }
|
||||
# { zig_target: i386-linux-musl, zig_flags: -march=i586, qemu: qemu-i386, zig_pic: -fPIE }
|
||||
- { zig_target: i386-windows-gnu }
|
||||
# mips and mipsel: bad hard-float code generation(??); or QEMU bug; or UPX bug; see https://github.com/upx/upx/issues/788
|
||||
- { zig_target: mips-linux-musl, zig_flags: -msoft-float, qemu: qemu-mips }
|
||||
- { zig_target: mipsel-linux-musl, zig_flags: -msoft-float, qemu: qemu-mipsel }
|
||||
- { zig_target: powerpc-linux-musl, qemu: qemu-ppc }
|
||||
# powerpc64: obscure problem with C++ exceptions in doctest checks when *NOT* using -fstack-protector
|
||||
# powerpc64: obscure problem with C++ exceptions in UPX doctest checks when *NOT* using -fstack-protector
|
||||
- { zig_target: powerpc64-linux-musl, zig_flags: -fstack-protector, qemu: qemu-ppc64 }
|
||||
- { zig_target: powerpc64le-linux-musl, qemu: qemu-ppc64le }
|
||||
- { zig_target: x86_64-linux-gnu.2.3.4 }
|
||||
- { zig_target: x86_64-linux-musl, qemu: qemu-x86_64 }
|
||||
# { zig_target: x86_64-linux-musl, qemu: qemu-x86_64, zig_pic: -fPIE }
|
||||
# { zig_target: x86_64-macos-none }
|
||||
|
@ -516,7 +516,7 @@ if(Threads_FOUND)
|
||||
elseif(UPX_CONFIG_REQUIRE_THREADS)
|
||||
message(FATAL_ERROR "ERROR: WITH_THREADS required")
|
||||
elseif(UPX_CONFIG_EXPECT_THREADS AND NOT UPX_CONFIG_DISABLE_THREADS)
|
||||
message(FATAL_ERROR "ERROR: WITH_THREADS expected")
|
||||
message(FATAL_ERROR "ERROR: WITH_THREADS expected; set UPX_CONFIG_EXPECT_THREADS=OFF to disable")
|
||||
endif()
|
||||
if(CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|None|Release)$")
|
||||
message(WARNING "WARNING: unsupported CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}; please use \"Debug\" or \"Release\"")
|
||||
|
@ -236,8 +236,8 @@ build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/c
|
||||
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-zstd/$$(notdir $$@)
|
||||
|
||||
# OLD names [deprecated]
|
||||
build/extra/scan-build/debug: build/analyze/clang-analyzer/debug
|
||||
build/extra/scan-build/release: build/analyze/clang-analyzer/release
|
||||
build/extra/scan-build/debug: build/analyze/clang-analyzer/debug PHONY
|
||||
build/extra/scan-build/release: build/analyze/clang-analyzer/release PHONY
|
||||
|
||||
#***********************************************************************
|
||||
# advanced: generic eXtra target
|
||||
|
@ -33,10 +33,6 @@ debug+test release+test all+test: PHONY; $(MAKE) -C $(top_srcd
|
||||
|
||||
test:: build/all+test PHONY
|
||||
|
||||
# OLD target names [deprecated]
|
||||
$(top_srcdir)/build/debug: build/debug PHONY
|
||||
$(top_srcdir)/build/release: build/release PHONY
|
||||
|
||||
#***********************************************************************
|
||||
# make run-testsuite
|
||||
# git clone https://github.com/upx/upx-testsuite.git
|
||||
|
40
src/bele.h
40
src/bele.h
@ -785,6 +785,26 @@ inline unsigned UPX_MIN(const LE32 &a, unsigned b) { return UPX_MIN(unsigned(a),
|
||||
// misc support
|
||||
**************************************************************************/
|
||||
|
||||
// for use with qsort()
|
||||
extern "C" {
|
||||
int __acc_cdecl_qsort be16_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be24_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be32_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be64_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le16_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le24_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le32_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le64_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be16_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort be24_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort be32_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort be64_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le16_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le24_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le32_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
|
||||
} // extern "C"
|
||||
|
||||
// <type_traits> upx_is_integral; see conf.h
|
||||
#define TT_UPX_IS_INTEGRAL(T) \
|
||||
template <> \
|
||||
@ -826,26 +846,6 @@ typedef LE64 NE64;
|
||||
#define ne64_compare_signed le64_compare_signed
|
||||
#endif
|
||||
|
||||
// for use with qsort()
|
||||
extern "C" {
|
||||
int __acc_cdecl_qsort be16_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be24_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be32_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be64_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le16_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le24_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le32_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le64_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be16_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort be24_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort be32_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort be64_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le16_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le24_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le32_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
|
||||
} // extern "C"
|
||||
|
||||
/*************************************************************************
|
||||
// Provide namespaces and classes to abstract endianness policies.
|
||||
//
|
||||
|
@ -92,9 +92,9 @@ private:
|
||||
#define C const noexcept override
|
||||
#endif
|
||||
|
||||
struct BEPolicy
|
||||
struct BEPolicy final
|
||||
#if defined(BELE_RTP)
|
||||
final : public AbstractPolicy
|
||||
: public AbstractPolicy
|
||||
#endif
|
||||
{
|
||||
explicit inline BEPolicy() noexcept {}
|
||||
@ -151,9 +151,9 @@ private:
|
||||
UPX_CXX_DISABLE_NEW_DELETE(BEPolicy)
|
||||
};
|
||||
|
||||
struct LEPolicy
|
||||
struct LEPolicy final
|
||||
#if defined(BELE_RTP)
|
||||
final : public AbstractPolicy
|
||||
: public AbstractPolicy
|
||||
#endif
|
||||
{
|
||||
explicit inline LEPolicy() noexcept {}
|
||||
|
@ -24,6 +24,9 @@
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
// doctest checks, and various tests to catch toolchain/qemu/sanitizer/valgrind/wine/etc
|
||||
// problems; grown historically
|
||||
|
||||
#include "../util/system_headers.h"
|
||||
#include <cmath> // std::isinf std::isnan
|
||||
#include "../conf.h"
|
||||
@ -376,6 +379,7 @@ struct TestFloat {
|
||||
static noinline Float add_div_x(Int a, Int b) { return Float(a + b) / Float(X); }
|
||||
static noinline Float sub_div_x(Int a, Int b) { return Float(a - b) / Float(X); }
|
||||
static noinline void check() noexcept {
|
||||
assert_noexcept(div(2 * X, Float(X)) == Float(2));
|
||||
assert_noexcept(add_div(X, X, Float(X)) == Float(2));
|
||||
assert_noexcept(add_div_x(X, X) == Float(2));
|
||||
assert_noexcept(sub_div(3 * X, X, Float(X)) == Float(2));
|
||||
@ -391,6 +395,7 @@ struct TestFloat {
|
||||
#else
|
||||
assert_noexcept(std::isnan(div(0, Float(0))));
|
||||
assert_noexcept(std::isinf(div(1, Float(0))));
|
||||
assert_noexcept(std::isinf(div(Int(-1), Float(0))));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -432,6 +437,19 @@ void upx_compiler_sanity_check(void) noexcept {
|
||||
|
||||
check_basic_floating_point();
|
||||
|
||||
// check_basic_decltype()
|
||||
{
|
||||
auto a = +0;
|
||||
constexpr auto b = -0;
|
||||
const auto &c = -1;
|
||||
COMPILE_TIME_ASSERT((std::is_same<int, decltype(a)>::value))
|
||||
COMPILE_TIME_ASSERT((std::is_same<const int, decltype(b)>::value))
|
||||
COMPILE_TIME_ASSERT((std::is_same<const int &, decltype(c)>::value))
|
||||
UNUSED(a);
|
||||
UNUSED(b);
|
||||
UNUSED(c);
|
||||
}
|
||||
|
||||
#define ACC_WANT_ACC_CHK_CH 1
|
||||
#undef ACCCHK_ASSERT
|
||||
#define ACCCHK_ASSERT(expr) ACC_COMPILE_TIME_ASSERT(expr)
|
||||
@ -646,7 +664,7 @@ void upx_compiler_sanity_check(void) noexcept {
|
||||
**************************************************************************/
|
||||
|
||||
TEST_CASE("assert_noexcept") {
|
||||
// just to make sure that our own assert() macros don't generate any warnings
|
||||
// just to make sure that our own assert() macros do not trigger any compiler warnings
|
||||
byte dummy = 0;
|
||||
byte *ptr1 = &dummy;
|
||||
const byte *const ptr2 = &dummy;
|
||||
@ -668,10 +686,13 @@ TEST_CASE("acc_vget") {
|
||||
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);
|
||||
if (acc_vget_int(1, 0) > 0)
|
||||
return;
|
||||
assert_noexcept(false);
|
||||
}
|
||||
|
||||
TEST_CASE("ptr_invalidate_and_poison") {
|
||||
int *ip = nullptr;
|
||||
int *ip = nullptr; // initialized
|
||||
ptr_invalidate_and_poison(ip);
|
||||
assert(ip != nullptr);
|
||||
(void) ip;
|
||||
@ -751,11 +772,13 @@ TEST_CASE("libc snprintf") {
|
||||
CHECK_EQ(strcmp(buf, "0X1A 0x1b 0x1c "), 0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST_CASE("libc qsort") {
|
||||
// runtime check that libc qsort() never compares identical objects
|
||||
// UPDATE: while only poor implementations of qsort() would actually do
|
||||
// this, it is probably allowed by the standard; so skip this test case
|
||||
// UPDATE: while only poor implementations of qsort() would actually do this
|
||||
// it is probably allowed by the standard, so skip this test by default
|
||||
if (!is_envvar_true("UPX_DEBUG_TEST_LIBC_QSORT"))
|
||||
return;
|
||||
|
||||
struct Elem {
|
||||
upx_uint16_t id;
|
||||
upx_uint16_t value;
|
||||
@ -765,8 +788,8 @@ TEST_CASE("libc qsort") {
|
||||
assert_noexcept(a->id != b->id); // check not IDENTICAL
|
||||
return a->value < b->value ? -1 : (a->value == b->value ? 0 : 1);
|
||||
}
|
||||
static bool check_sort(upx_sort_func_t sort, Elem *e, size_t n) {
|
||||
upx_uint32_t x = 5381 + n + ((upx_uintptr_t) e & 0xff);
|
||||
static noinline bool check_sort(upx_sort_func_t sort, Elem *e, size_t n) {
|
||||
upx_uint32_t x = 5381 + n + (upx_rand() & 0xff);
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
e[i].id = (upx_uint16_t) i;
|
||||
x = x * 33 + 1 + (i & 255);
|
||||
@ -782,18 +805,19 @@ TEST_CASE("libc qsort") {
|
||||
constexpr size_t N = 4096;
|
||||
Elem e[N];
|
||||
for (size_t n = 0; n <= N; n = 2 * n + 1) {
|
||||
// CHECK(Elem::check_sort(qsort, e, n)); // libc qsort()
|
||||
CHECK(Elem::check_sort(upx_gnomesort, e, n));
|
||||
CHECK(Elem::check_sort(upx_shellsort_memswap, e, n));
|
||||
CHECK(Elem::check_sort(upx_shellsort_memcpy, e, n));
|
||||
// system sort functions
|
||||
CHECK(Elem::check_sort(::qsort, e, n)); // libc qsort()
|
||||
#if UPX_CONFIG_USE_STABLE_SORT
|
||||
upx_sort_func_t wrap_stable_sort = [](void *aa, size_t nn, size_t, upx_compare_func_t cc) {
|
||||
upx_std_stable_sort<sizeof(Elem)>(aa, nn, cc);
|
||||
};
|
||||
CHECK(Elem::check_sort(wrap_stable_sort, e, n));
|
||||
CHECK(Elem::check_sort(wrap_stable_sort, e, n)); // std::stable_sort()
|
||||
#endif
|
||||
// UPX sort functions
|
||||
CHECK(Elem::check_sort(upx_gnomesort, e, n));
|
||||
CHECK(Elem::check_sort(upx_shellsort_memswap, e, n));
|
||||
CHECK(Elem::check_sort(upx_shellsort_memcpy, e, n));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
@ -27,24 +27,8 @@
|
||||
// lots of tests (and probably quite a number of redundant tests)
|
||||
// modern compilers will optimize away much of this code
|
||||
|
||||
#if 0 // TODO later
|
||||
// libc++ hardenining
|
||||
#if defined(__clang__) && defined(__clang_major__) && (__clang_major__ + 0 >= 18)
|
||||
#if DEBUG
|
||||
#define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEBUG
|
||||
#else
|
||||
#define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_EXTENSIVE
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__clang__) && defined(__clang_major__) && (__clang_major__ + 0 < 18)
|
||||
#if DEBUG
|
||||
#define _LIBCPP_ENABLE_ASSERTIONS 1
|
||||
#endif
|
||||
#endif
|
||||
#endif // TODO later
|
||||
|
||||
#include "../util/system_headers.h"
|
||||
#include <vector>
|
||||
#include <vector> // std::vector
|
||||
#include "../conf.h"
|
||||
|
||||
/*************************************************************************
|
||||
@ -125,7 +109,7 @@ ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_le("abc", "abz"))
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
TEST_CASE("libc++") {
|
||||
TEST_CASE("std::vector") {
|
||||
constexpr size_t N = 16;
|
||||
std::vector<int> v(N);
|
||||
CHECK(v.end() - v.begin() == N);
|
||||
@ -298,7 +282,7 @@ TEST_CASE("upx::ObjectDeleter 2") {
|
||||
}
|
||||
|
||||
TEST_CASE("upx::ptr_static_cast") {
|
||||
// check that we don't trigger any -Wcast-align warnings
|
||||
// check that we do not trigger any -Wcast-align warnings
|
||||
using upx::ptr_static_cast;
|
||||
void *vp = nullptr;
|
||||
byte *bp = nullptr;
|
||||
|
11
src/conf.h
11
src/conf.h
@ -162,7 +162,7 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(upx_charptr_unit_type) == 1)
|
||||
typedef upx_int64_t upx_off_t;
|
||||
#undef off_t
|
||||
#if 0
|
||||
// TODO cleanup: at some future point we can do this:
|
||||
// TODO later cleanup: at some future point we can do this:
|
||||
#define off_t DO_NOT_USE_off_t
|
||||
#else
|
||||
#define off_t upx_off_t
|
||||
@ -230,12 +230,6 @@ typedef upx_int64_t upx_off_t;
|
||||
#undef sopen
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DUP) && (HAVE_DUP + 0 == 0)
|
||||
// TODO later: add upx_fd_dup() util
|
||||
#undef dup
|
||||
#define dup(x) (-1)
|
||||
#endif
|
||||
|
||||
#ifndef STDIN_FILENO
|
||||
#define STDIN_FILENO (fileno(stdin))
|
||||
#endif
|
||||
@ -338,7 +332,7 @@ typedef upx_int64_t upx_off_t;
|
||||
// TODO later: check __MINGW_PRINTF_FORMAT
|
||||
#if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__)
|
||||
#define attribute_format(a, b) __attribute__((__format__(__gnu_printf__, a, b)))
|
||||
#elif (ACC_CC_CLANG || ACC_CC_GNUC)
|
||||
#elif defined(__clang__) || defined(__GNUC__)
|
||||
#define attribute_format(a, b) __attribute__((__format__(__printf__, a, b)))
|
||||
#else
|
||||
#define attribute_format(a, b) /*empty*/
|
||||
@ -442,6 +436,7 @@ inline void mem_clear(T *object) noexcept {
|
||||
static_assert(size >= 1 && size <= UPX_RSIZE_MAX_MEM);
|
||||
memset((void *) object, 0, size);
|
||||
}
|
||||
// disable some overloads
|
||||
#if defined(__clang__) || __GNUC__ != 7
|
||||
template <class T>
|
||||
inline void mem_clear(T (&array)[]) noexcept DELETED_FUNCTION;
|
||||
|
@ -203,7 +203,7 @@ const char *prettyName(const char *n) noexcept {
|
||||
n++;
|
||||
else if (*n == ' ')
|
||||
n++;
|
||||
else if (strncmp(n, "class ", 6) == 0) // Visual C++ (msvc)
|
||||
else if (strncmp(n, "class ", 6) == 0) // Visual C++ (MSVC)
|
||||
n += 6;
|
||||
else
|
||||
break;
|
||||
|
19
src/file.cpp
19
src/file.cpp
@ -40,6 +40,7 @@
|
||||
#else
|
||||
UNUSED(name);
|
||||
UNUSED(mode);
|
||||
// no error
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -88,7 +89,7 @@ bool FileBase::do_sopen() {
|
||||
else {
|
||||
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||
_fd = ::open(_name, _flags | _shflags, _mode);
|
||||
#elif defined(__MINT__)
|
||||
#elif (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
|
||||
_fd = ::open(_name, _flags | (_shflags & O_SHMODE), _mode);
|
||||
#elif defined(SH_DENYRW)
|
||||
_fd = ::sopen(_name, _flags, _shflags, _mode);
|
||||
@ -98,6 +99,7 @@ bool FileBase::do_sopen() {
|
||||
}
|
||||
if (_fd < 0)
|
||||
return false;
|
||||
st.st_size = 0;
|
||||
if (::fstat(_fd, &st) != 0)
|
||||
throwIOException(_name, errno);
|
||||
_length = st.st_size;
|
||||
@ -212,6 +214,20 @@ upx_off_t InputFile::seek(upx_off_t off, int whence) {
|
||||
|
||||
upx_off_t InputFile::st_size_orig() const { return _length_orig; }
|
||||
|
||||
int InputFile::dup() may_throw {
|
||||
if (!isOpen())
|
||||
throwIOException("bad dup");
|
||||
#if defined(HAVE_DUP) && (HAVE_DUP + 0 == 0)
|
||||
errno = ENOSYS;
|
||||
int r = -1;
|
||||
#else
|
||||
int r = ::dup(getFd());
|
||||
#endif
|
||||
if (r < 0)
|
||||
throwIOException("dup", errno);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// OutputFile
|
||||
**************************************************************************/
|
||||
@ -333,6 +349,7 @@ void OutputFile::set_extent(upx_off_t offset, upx_off_t length) {
|
||||
super::set_extent(offset, length);
|
||||
bytes_written = 0;
|
||||
if (0 == offset && 0xffffffffLL == length) { // TODO: check all callers of this method
|
||||
st.st_size = 0;
|
||||
if (::fstat(_fd, &st) != 0)
|
||||
throwIOException(_name, errno);
|
||||
_length = st.st_size - offset;
|
||||
|
@ -88,6 +88,8 @@ public:
|
||||
virtual upx_off_t seek(upx_off_t off, int whence) override;
|
||||
upx_off_t st_size_orig() const;
|
||||
|
||||
noinline int dup() may_throw;
|
||||
|
||||
protected:
|
||||
upx_off_t _length_orig = 0;
|
||||
};
|
||||
|
@ -60,7 +60,7 @@ ElfLinker::Section::Section(const char *n, const void *i, unsigned s, unsigned a
|
||||
: name(nullptr), output(nullptr), size(s), offset(0), p2align(a), next(nullptr) {
|
||||
name = strdup(n);
|
||||
assert(name != nullptr);
|
||||
input = malloc(s + 1);
|
||||
input = ::malloc(s + 1);
|
||||
assert(input != nullptr);
|
||||
if (s != 0) {
|
||||
assert(i != nullptr);
|
||||
@ -70,8 +70,8 @@ ElfLinker::Section::Section(const char *n, const void *i, unsigned s, unsigned a
|
||||
}
|
||||
|
||||
ElfLinker::Section::~Section() noexcept {
|
||||
free(name);
|
||||
free(input);
|
||||
::free(name);
|
||||
::free(input);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@ -85,7 +85,7 @@ ElfLinker::Symbol::Symbol(const char *n, Section *s, upx_uint64_t o)
|
||||
assert(section != nullptr);
|
||||
}
|
||||
|
||||
ElfLinker::Symbol::~Symbol() noexcept { free(name); }
|
||||
ElfLinker::Symbol::~Symbol() noexcept { ::free(name); }
|
||||
|
||||
/*************************************************************************
|
||||
// Relocation
|
||||
@ -110,13 +110,13 @@ ElfLinker::~ElfLinker() noexcept {
|
||||
unsigned ic;
|
||||
for (ic = 0; ic < nsections; ic++)
|
||||
delete sections[ic];
|
||||
free(sections);
|
||||
::free(sections);
|
||||
for (ic = 0; ic < nsymbols; ic++)
|
||||
delete symbols[ic];
|
||||
free(symbols);
|
||||
::free(symbols);
|
||||
for (ic = 0; ic < nrelocations; ic++)
|
||||
delete relocations[ic];
|
||||
free(relocations);
|
||||
::free(relocations);
|
||||
}
|
||||
|
||||
void ElfLinker::init(const void *pdata_v, int plen, unsigned pxtra) {
|
||||
@ -425,7 +425,7 @@ int ElfLinker::addLoader(const char *sname) {
|
||||
}
|
||||
sect += strlen(sect) + 1;
|
||||
}
|
||||
free(begin);
|
||||
::free(begin);
|
||||
return outputlen;
|
||||
}
|
||||
|
||||
|
@ -923,7 +923,7 @@ int main_get_options(int argc, char **argv) {
|
||||
// atari/tos
|
||||
{"split-segments", 0x90, N, 650},
|
||||
// darwin/macho
|
||||
{"force-macos", 0x90, N, 690}, // undocumented temporary until we fix macOS 13+
|
||||
{"force-macos", 0x90, N, 690}, // undocumented temporary option until we do fix macOS 13+
|
||||
// djgpp2/coff
|
||||
{"coff", 0x90, N, 610}, // produce COFF output
|
||||
// dos/exe
|
||||
@ -1355,9 +1355,9 @@ int __acc_cdecl_main main(int argc, char *argv[]) /*noexcept*/ {
|
||||
#endif
|
||||
acc_wildargv(&argc, &argv);
|
||||
#if defined(__wasi__)
|
||||
srand((int) time(nullptr));
|
||||
::srand((unsigned) time(nullptr));
|
||||
#else
|
||||
srand((int) clock());
|
||||
::srand((unsigned) clock());
|
||||
#endif
|
||||
|
||||
// info: main() is implicitly "noexcept", so we need a try block
|
||||
|
@ -28,9 +28,10 @@
|
||||
#pragma once
|
||||
|
||||
struct Options;
|
||||
extern Options *opt; // global options, see class PackMaster for per-file local options
|
||||
#define options_t Options // old name
|
||||
|
||||
extern Options *opt; // global options, see class PackMaster for per-file local options
|
||||
|
||||
#if WITH_THREADS
|
||||
extern std::mutex opt_lock_mutex;
|
||||
#endif
|
||||
@ -177,6 +178,9 @@ struct Options final {
|
||||
int strip_relocs;
|
||||
const char *keep_resource;
|
||||
} win32_pe;
|
||||
|
||||
private: // UPX conventions
|
||||
UPX_CXX_DISABLE_NEW_DELETE(Options)
|
||||
};
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
@ -267,7 +267,7 @@ int PackVmlinuzI386::decompressKernel()
|
||||
fd_pos = -1;
|
||||
// open
|
||||
fi->seek(gzoff, SEEK_SET);
|
||||
fd = dup(fi->getFd());
|
||||
fd = fi->dup();
|
||||
if (fd < 0)
|
||||
break;
|
||||
gzFile zf = gzdopen(fd, "rb");
|
||||
@ -849,7 +849,7 @@ int PackVmlinuzARMEL::decompressKernel()
|
||||
fd_pos = -1;
|
||||
// open
|
||||
fi->seek(gzoff, SEEK_SET);
|
||||
fd = dup(fi->getFd());
|
||||
fd = fi->dup();
|
||||
if (fd < 0)
|
||||
break;
|
||||
gzFile zf = gzdopen(fd, "rb");
|
||||
|
@ -743,6 +743,7 @@ tribool PackWcle::canUnpack() {
|
||||
return readPackHeader(len) ? 1 : -1;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void PackWcle::virt2rela(const le_object_table_entry_t *entr, unsigned *objn, unsigned *addr) {
|
||||
for (; *objn > 1; objn[0]--) {
|
||||
if (entr[*objn - 1].my_base_address > *addr)
|
||||
|
@ -495,7 +495,7 @@ unsigned Packer::getRandomId() const {
|
||||
#endif
|
||||
id ^= (unsigned) fi->st.st_ino;
|
||||
id ^= (unsigned) fi->st.st_atime;
|
||||
id ^= (unsigned) rand();
|
||||
id ^= (unsigned) upx_rand();
|
||||
}
|
||||
return id;
|
||||
}
|
||||
@ -947,7 +947,7 @@ int Packer::prepareMethods(int *methods, int ph_method, const int *all_methods)
|
||||
}
|
||||
// debug
|
||||
if (opt->debug.use_random_method && nmethods >= 2) {
|
||||
int method = methods[rand() % nmethods];
|
||||
int method = methods[upx_rand() % nmethods];
|
||||
methods[0] = method;
|
||||
nmethods = 1;
|
||||
NO_printf("\nuse_random_method = %d\n", method);
|
||||
@ -1015,7 +1015,7 @@ done:
|
||||
filters[nfilters++] = 0;
|
||||
// debug
|
||||
if (opt->debug.use_random_filter && nfilters >= 3 && filters[nfilters - 1] == 0) {
|
||||
int filter_id = filters[rand() % (nfilters - 1)];
|
||||
int filter_id = filters[upx_rand() % (nfilters - 1)];
|
||||
if (filter_id > 0) {
|
||||
filters[0] = filter_id;
|
||||
filters[1] = 0;
|
||||
|
@ -84,10 +84,14 @@ struct PackHeader final {
|
||||
|
||||
// info fields set by Packer::compressWithFilters()
|
||||
unsigned overlap_overhead;
|
||||
|
||||
private: // UPX conventions
|
||||
UPX_CXX_DISABLE_ADDRESS(PackHeader)
|
||||
UPX_CXX_DISABLE_NEW_DELETE(PackHeader)
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
// ph default util functions
|
||||
// PackHeader ph util functions
|
||||
**************************************************************************/
|
||||
|
||||
bool ph_is_forced_method(int method) noexcept; // predicate
|
||||
|
@ -59,6 +59,11 @@ private:
|
||||
// setup local options for each file
|
||||
Options local_options;
|
||||
Options *saved_opt = nullptr;
|
||||
|
||||
private: // UPX conventions
|
||||
UPX_CXX_DISABLE_ADDRESS(PackMaster)
|
||||
UPX_CXX_DISABLE_COPY_MOVE(PackMaster)
|
||||
UPX_CXX_DISABLE_NEW_DELETE(PackMaster)
|
||||
};
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
@ -215,7 +215,7 @@ int PeFile::readFileHeader() {
|
||||
|
||||
PeFile::Interval::Interval(SPAN_P(byte) b) : base(b) {}
|
||||
|
||||
PeFile::Interval::~Interval() noexcept { free(ivarr); }
|
||||
PeFile::Interval::~Interval() noexcept { ::free(ivarr); }
|
||||
|
||||
int __acc_cdecl_qsort PeFile::Interval::compare(const void *p1, const void *p2) {
|
||||
const interval *i1 = (const interval *) p1;
|
||||
@ -1175,14 +1175,14 @@ PeFile::Export::Export(char *_base) : base(_base), iv((byte *) _base) {
|
||||
}
|
||||
|
||||
PeFile::Export::~Export() noexcept {
|
||||
free(ename);
|
||||
::free(ename);
|
||||
delete[] functionptrs;
|
||||
delete[] ordinals;
|
||||
if (names) {
|
||||
const unsigned limit = edir.names + edir.functions;
|
||||
for (unsigned ic = 0; ic < limit; ic++)
|
||||
if (names[ic])
|
||||
free(names[ic]); // allocated by strdup()
|
||||
::free(names[ic]); // allocated by strdup()
|
||||
delete[] names;
|
||||
}
|
||||
}
|
||||
|
4
src/ui.h
4
src/ui.h
@ -104,6 +104,10 @@ protected:
|
||||
static unsigned update_u_len;
|
||||
static unsigned update_fc_len;
|
||||
static unsigned update_fu_len;
|
||||
|
||||
private: // UPX conventions
|
||||
UPX_CXX_DISABLE_ADDRESS(UiPacker)
|
||||
UPX_CXX_DISABLE_COPY_MOVE(UiPacker)
|
||||
};
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
@ -427,7 +427,7 @@ template <class T>
|
||||
inline void owner_free(OwningPointer(T)(&object)) noexcept {
|
||||
static_assert(!std::is_class_v<T>); // UPX convention
|
||||
if (object != nullptr) {
|
||||
free((T *) object);
|
||||
::free((T *) object);
|
||||
object = nullptr;
|
||||
}
|
||||
assert_noexcept((T *) object == nullptr);
|
||||
|
@ -128,7 +128,7 @@ int upx_safe_vasprintf(char **ptr, const char *format, va_list ap) {
|
||||
va_end(ap_copy);
|
||||
|
||||
if (len >= 0) {
|
||||
*ptr = (char *) malloc(len + 1);
|
||||
*ptr = (char *) ::malloc(len + 1);
|
||||
assert(*ptr != nullptr);
|
||||
if (*ptr == nullptr)
|
||||
return -1;
|
||||
|
@ -55,7 +55,7 @@
|
||||
#if DEBUG
|
||||
#define _LIBCPP_ENABLE_ASSERTIONS 1
|
||||
#endif
|
||||
#endif
|
||||
#endif // clang >= 18
|
||||
#endif // TODO later
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
@ -254,17 +254,19 @@ TEST_CASE("ptr_check_no_overlap 3") {
|
||||
// stdlib
|
||||
**************************************************************************/
|
||||
|
||||
int upx_rand(void) noexcept { return ::rand(); }
|
||||
|
||||
void *upx_calloc(size_t n, size_t element_size) may_throw {
|
||||
size_t bytes = mem_size(element_size, n); // assert size
|
||||
void *p = malloc(bytes);
|
||||
void *p = ::malloc(bytes);
|
||||
if (p != nullptr)
|
||||
memset(p, 0, bytes);
|
||||
return p;
|
||||
}
|
||||
|
||||
// simple unoptimized memswap()
|
||||
void upx_memswap(void *a, void *b, size_t n) noexcept {
|
||||
if (a != b && n != 0) {
|
||||
void upx_memswap(void *a, void *b, size_t bytes) noexcept {
|
||||
if (a != b && bytes != 0) {
|
||||
byte *x = (byte *) a;
|
||||
byte *y = (byte *) b;
|
||||
do {
|
||||
@ -273,16 +275,16 @@ void upx_memswap(void *a, void *b, size_t n) noexcept {
|
||||
byte tmp = *x; // NOLINT(*core.uninitialized.Assign) // bogus clang-analyzer warning
|
||||
*x++ = *y;
|
||||
*y++ = tmp;
|
||||
} while (--n != 0);
|
||||
} while (--bytes != 0);
|
||||
}
|
||||
}
|
||||
|
||||
// much better memswap(), optimized for our use case in sort functions below
|
||||
static void memswap_no_overlap(byte *a, byte *b, size_t n) noexcept {
|
||||
static inline void memswap_no_overlap(byte *a, byte *b, size_t bytes) noexcept {
|
||||
#if defined(__clang__) && __clang_major__ < 15
|
||||
// work around a clang < 15 ICE (Internal Compiler Error)
|
||||
// @COMPILER_BUG @CLANG_BUG
|
||||
upx_memswap(a, b, n);
|
||||
upx_memswap(a, b, bytes);
|
||||
#else // clang bug
|
||||
upx_alignas_max byte tmp_buf[16];
|
||||
#define SWAP(x) \
|
||||
@ -294,15 +296,15 @@ static void memswap_no_overlap(byte *a, byte *b, size_t n) noexcept {
|
||||
b += x; \
|
||||
} while (0)
|
||||
|
||||
for (; n >= 16; n -= 16)
|
||||
for (; bytes >= 16; bytes -= 16)
|
||||
SWAP(16);
|
||||
if (n & 8)
|
||||
if (bytes & 8)
|
||||
SWAP(8);
|
||||
if (n & 4)
|
||||
if (bytes & 4)
|
||||
SWAP(4);
|
||||
if (n & 2)
|
||||
if (bytes & 2)
|
||||
SWAP(2);
|
||||
if (n & 1) {
|
||||
if (bytes & 1) {
|
||||
byte tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
@ -347,7 +349,7 @@ void upx_shellsort_memcpy(void *array, size_t n, size_t element_size, upx_compar
|
||||
upx_alignas_max byte tmp_buf[MAX_INLINE_ELEMENT_SIZE]; // buffer for one element
|
||||
byte *tmp = tmp_buf;
|
||||
if (element_size > MAX_INLINE_ELEMENT_SIZE) {
|
||||
tmp = (byte *) malloc(element_size);
|
||||
tmp = (byte *) ::malloc(element_size);
|
||||
assert(tmp != nullptr);
|
||||
}
|
||||
size_t gap = 0; // 0, 1, 4, 13, 40, 121, 364, 1093, ...
|
||||
@ -368,7 +370,7 @@ void upx_shellsort_memcpy(void *array, size_t n, size_t element_size, upx_compar
|
||||
}
|
||||
}
|
||||
if (element_size > MAX_INLINE_ELEMENT_SIZE)
|
||||
free(tmp);
|
||||
::free(tmp);
|
||||
}
|
||||
|
||||
// wrap std::stable_sort()
|
||||
@ -391,9 +393,10 @@ void upx_std_stable_sort(void *array, size_t n, upx_compare_func_t compare) {
|
||||
}
|
||||
|
||||
#if UPX_CONFIG_USE_STABLE_SORT
|
||||
// instantiate function templates for all element sizes we need; efficient run time, but code size
|
||||
// bloat (about 4KiB code size for each function with my current libstdc++); not really needed as
|
||||
// libc qsort() is good enough for our use cases
|
||||
// instantiate function templates for all element sizes we need; efficient
|
||||
// run-time, but code size bloat (about 4KiB code size for each function
|
||||
// with my current libstdc++); not really needed as libc qsort() is
|
||||
// good enough for our use cases
|
||||
template void upx_std_stable_sort<1>(void *, size_t, upx_compare_func_t);
|
||||
template void upx_std_stable_sort<2>(void *, size_t, upx_compare_func_t);
|
||||
template void upx_std_stable_sort<4>(void *, size_t, upx_compare_func_t);
|
||||
@ -405,7 +408,7 @@ template void upx_std_stable_sort<56>(void *, size_t, upx_compare_func_t);
|
||||
template void upx_std_stable_sort<72>(void *, size_t, upx_compare_func_t);
|
||||
#endif
|
||||
|
||||
#if !defined(DOCTEST_CONFIG_DISABLE) && DEBUG >= 1
|
||||
#if !defined(DOCTEST_CONFIG_DISABLE) && DEBUG
|
||||
#if __cplusplus >= 202002L // use C++20 std::next_permutation() to test all permutations
|
||||
namespace {
|
||||
template <class ElementType, upx_compare_func_t CompareFunc>
|
||||
@ -588,7 +591,7 @@ int find(const void *buf, int blen, const void *what, int wlen) noexcept {
|
||||
return -1;
|
||||
|
||||
const byte *b = (const byte *) buf;
|
||||
byte first_byte = *(const byte *) what;
|
||||
const byte first_byte = *(const byte *) what;
|
||||
|
||||
blen -= wlen;
|
||||
for (int i = 0; i <= blen; i++, b++)
|
||||
@ -769,8 +772,8 @@ int fn_strcmp(const char *n1, const char *n2) {
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
// UPX convention: any environment variable that is set and is not strictly equal to "0" is true
|
||||
bool is_envvar_true(const char *envvar, const char *alternate_name) noexcept {
|
||||
// UPX convention: any environment variable that is set and is not strictly equal to "0" is true
|
||||
const char *e = getenv(envvar);
|
||||
if (e != nullptr && e[0])
|
||||
return strcmp(e, "0") != 0;
|
||||
|
@ -143,9 +143,11 @@ inline void ptr_invalidate_and_poison(T *(&ptr)) noexcept {
|
||||
// stdlib
|
||||
**************************************************************************/
|
||||
|
||||
void *upx_calloc(size_t n, size_t element_size) may_throw;
|
||||
noinline void *upx_calloc(size_t n, size_t element_size) may_throw;
|
||||
|
||||
void upx_memswap(void *a, void *b, size_t n) noexcept;
|
||||
void upx_memswap(void *a, void *b, size_t bytes) noexcept;
|
||||
|
||||
noinline int upx_rand(void) noexcept;
|
||||
|
||||
typedef int(__acc_cdecl_qsort *upx_compare_func_t)(const void *, const void *);
|
||||
typedef void (*upx_sort_func_t)(void *array, size_t n, size_t element_size, upx_compare_func_t);
|
||||
@ -165,7 +167,7 @@ void upx_std_stable_sort(void *array, size_t n, upx_compare_func_t compare);
|
||||
upx_std_stable_sort<(element_size)>((a), (n), (compare))
|
||||
#else
|
||||
// use libc qsort(); good enough for our use cases
|
||||
#define upx_qsort qsort
|
||||
#define upx_qsort ::qsort
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -30,7 +30,7 @@
|
||||
// of class PackerBase which then does the actual work.
|
||||
// And see p_com.cpp for a simple executable format.
|
||||
//
|
||||
// This file also has the burden to deal with all those pesky low-level
|
||||
// And this file also has the burden to deal with all those pesky low-level
|
||||
// file handling issues.
|
||||
|
||||
#define WANT_WINDOWS_LEAN_H 1 // _get_osfhandle, GetFileTime, SetFileTime
|
||||
@ -47,7 +47,7 @@
|
||||
#include "util/membuffer.h"
|
||||
|
||||
#if USE_UTIMENSAT && defined(AT_FDCWD)
|
||||
#elif (defined(_WIN32) || defined(__CYGWIN__)) && 1
|
||||
#elif defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define USE_SETFILETIME 1
|
||||
#elif (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||
#define USE_FTIME 1
|
||||
|
Loading…
Reference in New Issue
Block a user