all: assorted cleanups and updates
Changes include: - add a bunch of "noexcept", mostly to operators and forceinline - use "uchar" - use "charptr" - rename options_t to Options - add ptr_check_no_overlap() - rewrite p_exe.cpp, NFCI - clang-format help.cpp - spelling fixes
This commit is contained in:
+84
-60
@@ -100,6 +100,7 @@ ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) == 255) // -funsigned-char
|
||||
# pragma warning(error: 4805)
|
||||
#endif
|
||||
#endif // !UPX_CONFIG_DISABLE_WSTRICT && !UPX_CONFIG_DISABLE_WERROR
|
||||
|
||||
// disable some warnings
|
||||
#if (ACC_CC_MSC)
|
||||
# pragma warning(disable: 4244) // -Wconversion
|
||||
@@ -124,22 +125,30 @@ ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) == 255) // -funsigned-char
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#if __STDC_NO_ATOMICS__ || 1
|
||||
// UPX currently does not use multithreading
|
||||
#define upx_std_atomic(Type) Type
|
||||
//#define upx_std_atomic(Type) typename std::add_volatile<Type>::type
|
||||
#define upx_std_once_flag upx_std_atomic(size_t)
|
||||
template <class NoexceptCallable>
|
||||
inline void upx_std_call_once(upx_std_once_flag &flag, NoexceptCallable &&f) {
|
||||
if (__acc_unlikely(!flag)) { flag = 1; f(); }
|
||||
}
|
||||
#else
|
||||
|
||||
// multithreading (UPX currently does not use multithreading)
|
||||
#ifndef WITH_THREADS
|
||||
# define WITH_THREADS 0
|
||||
#endif
|
||||
#if __STDC_NO_ATOMICS__
|
||||
# undef WITH_THREADS
|
||||
#endif
|
||||
#if (WITH_THREADS)
|
||||
#define upx_thread_local thread_local
|
||||
#include <atomic>
|
||||
#define upx_std_atomic(Type) std::atomic<Type>
|
||||
#include <mutex>
|
||||
#define upx_std_once_flag std::once_flag
|
||||
#define upx_std_call_once std::call_once
|
||||
#endif
|
||||
#else
|
||||
#define upx_thread_local /*empty*/
|
||||
#define upx_std_atomic(Type) Type
|
||||
#define upx_std_once_flag upx_std_atomic(size_t)
|
||||
template <class NoexceptCallable>
|
||||
inline void upx_std_call_once(upx_std_once_flag &flag, NoexceptCallable &&f) {
|
||||
if (__acc_unlikely(!flag)) { flag = 1; f(); }
|
||||
}
|
||||
#endif // WITH_THREADS
|
||||
|
||||
// C++ submodule headers
|
||||
#include <doctest/doctest/parts/doctest_fwd.h>
|
||||
@@ -166,16 +175,39 @@ inline void upx_std_call_once(upx_std_once_flag &flag, NoexceptCallable &&f) {
|
||||
|
||||
// <type_traits> C++20 std::is_bounded_array
|
||||
template <class T>
|
||||
struct std_is_bounded_array : public std::false_type {};
|
||||
struct upx_std_is_bounded_array : public std::false_type {};
|
||||
template <class T, size_t N>
|
||||
struct std_is_bounded_array<T[N]> : public std::true_type {};
|
||||
struct upx_std_is_bounded_array<T[N]> : public std::true_type {};
|
||||
template <class T>
|
||||
inline constexpr bool upx_std_is_bounded_array_v = upx_std_is_bounded_array<T>::value;
|
||||
|
||||
// see bele.h
|
||||
template <class T>
|
||||
struct upx_is_integral : public std::is_integral<T> {};
|
||||
template <class T>
|
||||
inline constexpr bool upx_is_integral_v = upx_is_integral<T>::value;
|
||||
|
||||
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
|
||||
// horrible hack for broken compiler
|
||||
#define upx_fake_alignas_1 __attribute__((__aligned__(1),__packed__))
|
||||
#define upx_fake_alignas_16 __attribute__((__aligned__(2))) // object file maximum 2 ???
|
||||
#define upx_fake_alignas__(a) upx_fake_alignas_ ## a
|
||||
#define alignas(x) upx_fake_alignas__(x)
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// core
|
||||
**************************************************************************/
|
||||
|
||||
// intergral types
|
||||
// protect against integer overflows and malicious header fields
|
||||
// see C 11 standard, Annex K
|
||||
typedef size_t upx_rsize_t;
|
||||
#define UPX_RSIZE_MAX UPX_RSIZE_MAX_MEM
|
||||
#define UPX_RSIZE_MAX_MEM (768 * 1024 * 1024) // DO NOT CHANGE !!!
|
||||
#define UPX_RSIZE_MAX_STR (256 * 1024)
|
||||
|
||||
// integral types
|
||||
typedef acc_int8_t upx_int8_t;
|
||||
typedef acc_uint8_t upx_uint8_t;
|
||||
typedef acc_int16_t upx_int16_t;
|
||||
@@ -186,16 +218,17 @@ typedef acc_int64_t upx_int64_t;
|
||||
typedef acc_uint64_t upx_uint64_t;
|
||||
typedef acc_uintptr_t upx_uintptr_t;
|
||||
|
||||
// convention: use "byte" when dealing with data; use "char/uchar" when dealing
|
||||
// with strings; use "upx_uint8_t" when dealing with small integers
|
||||
typedef unsigned char byte;
|
||||
#define upx_byte byte
|
||||
#define upx_bytep byte *
|
||||
|
||||
// protect against integer overflows and malicious header fields
|
||||
// see C 11 standard, Annex K
|
||||
typedef size_t upx_rsize_t;
|
||||
#define UPX_RSIZE_MAX UPX_RSIZE_MAX_MEM
|
||||
#define UPX_RSIZE_MAX_MEM (768 * 1024 * 1024) // DO NOT CHANGE !!!
|
||||
#define UPX_RSIZE_MAX_STR (1024 * 1024)
|
||||
typedef unsigned char uchar;
|
||||
// use "charptr" when dealing with pointer arithmetics
|
||||
#define charptr upx_charptr_unit_type *
|
||||
// upx_charptr_unit_type is some opaque type with sizeof(type) == 1
|
||||
struct alignas(1) upx_charptr_unit_type { char dummy; };
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(upx_charptr_unit_type) == 1)
|
||||
|
||||
// using the system off_t was a bad idea even back in 199x...
|
||||
typedef upx_int64_t upx_off_t;
|
||||
@@ -244,8 +277,8 @@ typedef upx_int64_t upx_off_t;
|
||||
#endif
|
||||
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||
# undef sopen
|
||||
# undef __unix__
|
||||
# undef __unix
|
||||
# undef __unix__
|
||||
#endif
|
||||
|
||||
#ifndef STDIN_FILENO
|
||||
@@ -304,7 +337,7 @@ typedef upx_int64_t upx_off_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// avoid warnings about shadowing global functions
|
||||
// avoid warnings about shadowing global symbols
|
||||
#undef _base
|
||||
#undef basename
|
||||
#undef index
|
||||
@@ -391,14 +424,6 @@ inline void NO_fprintf(FILE *, const char *, ...) {}
|
||||
#define __packed_struct(s) struct alignas(1) s {
|
||||
#define __packed_struct_end() };
|
||||
|
||||
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
|
||||
// horrible hack for broken compiler
|
||||
#define upx_fake_alignas_1 __attribute__((__aligned__(1),__packed__))
|
||||
#define upx_fake_alignas_16 __attribute__((__aligned__(2))) // object file maximum 2 ???
|
||||
#define upx_fake_alignas__(a) upx_fake_alignas_ ## a
|
||||
#define alignas(x) upx_fake_alignas__(x)
|
||||
#endif
|
||||
|
||||
#define COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a,b) { \
|
||||
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \
|
||||
struct alignas(1) acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; }; \
|
||||
@@ -426,15 +451,13 @@ inline const T& UPX_MAX(const T& a, const T& b) { if (a < b) return b; return a;
|
||||
template <class T>
|
||||
inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b; }
|
||||
|
||||
template <size_t TypeSize>
|
||||
struct USizeOfTypeImpl {
|
||||
static forceinline constexpr unsigned value() {
|
||||
COMPILE_TIME_ASSERT(TypeSize >= 1 && TypeSize <= 64 * 1024) // arbitrary limit
|
||||
return ACC_ICONV(unsigned, TypeSize);
|
||||
}
|
||||
template <size_t Size>
|
||||
struct UnsignedSizeOf {
|
||||
static_assert(Size >= 1 && Size <= UPX_RSIZE_MAX_MEM);
|
||||
static constexpr unsigned value = unsigned(Size);
|
||||
};
|
||||
#define usizeof(type) (USizeOfTypeImpl<sizeof(type)>::value())
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == 4)
|
||||
#define usizeof(expr) (UnsignedSizeOf<sizeof(expr)>::value)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == sizeof(int))
|
||||
|
||||
// An Array allocates memory on the heap, and automatically
|
||||
// gets destructed when leaving scope or on exceptions.
|
||||
@@ -442,16 +465,16 @@ ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == 4)
|
||||
MemBuffer var ## _membuf(mem_size(sizeof(type), size)); \
|
||||
type * const var = ACC_STATIC_CAST(type *, var ## _membuf.getVoidPtr())
|
||||
|
||||
#define ByteArray(var, size) Array(unsigned char, var, size)
|
||||
#define ByteArray(var, size) Array(byte, var, size)
|
||||
|
||||
|
||||
class noncopyable
|
||||
{
|
||||
protected:
|
||||
inline noncopyable() {}
|
||||
inline ~noncopyable() {}
|
||||
inline noncopyable() noexcept {}
|
||||
inline ~noncopyable() noexcept {}
|
||||
private:
|
||||
noncopyable(const noncopyable &) DELETED_FUNCTION; // copy constuctor
|
||||
noncopyable(const noncopyable &) DELETED_FUNCTION; // copy constructor
|
||||
noncopyable& operator=(const noncopyable &) DELETED_FUNCTION; // copy assignment
|
||||
noncopyable(noncopyable &&) DELETED_FUNCTION; // move constructor
|
||||
noncopyable& operator=(noncopyable &&) DELETED_FUNCTION; // move assignment
|
||||
@@ -466,7 +489,7 @@ 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));
|
||||
return (uchar)*a < (uchar)*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);
|
||||
@@ -644,7 +667,7 @@ struct upx_callback_t
|
||||
upx_progress_func_t nprogress;
|
||||
void *user;
|
||||
|
||||
void reset() { memset(this, 0, sizeof(*this)); }
|
||||
void reset() noexcept { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
|
||||
@@ -670,7 +693,7 @@ struct OptVar
|
||||
assertValue(v);
|
||||
}
|
||||
|
||||
OptVar() : v(default_value), is_set(false) { }
|
||||
OptVar() noexcept : v(default_value), is_set(false) { }
|
||||
OptVar& operator= (const T &other) {
|
||||
assertValue(other);
|
||||
v = other;
|
||||
@@ -678,8 +701,8 @@ struct OptVar
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset() { v = default_value; is_set = false; }
|
||||
operator T () const { return v; }
|
||||
void reset() noexcept { v = default_value; is_set = false; }
|
||||
operator T () const noexcept { return v; }
|
||||
|
||||
T v;
|
||||
bool is_set;
|
||||
@@ -818,26 +841,16 @@ struct upx_compress_result_t
|
||||
// globals
|
||||
**************************************************************************/
|
||||
|
||||
#include "util/snprintf.h" // must get included first!
|
||||
#include "options.h"
|
||||
#include "except.h"
|
||||
#include "bele.h"
|
||||
#include "console/console.h"
|
||||
#include "util/util.h"
|
||||
|
||||
// classes
|
||||
class ElfLinker;
|
||||
typedef ElfLinker Linker;
|
||||
class Throwable;
|
||||
|
||||
// util/membuffer.h
|
||||
class MemBuffer;
|
||||
void *membuffer_get_void_ptr(MemBuffer &mb);
|
||||
unsigned membuffer_get_size(MemBuffer &mb);
|
||||
|
||||
// xspan
|
||||
#include "util/raw_bytes.h"
|
||||
#include "util/xspan.h"
|
||||
|
||||
// util/dt_check.cpp
|
||||
void upx_compiler_sanity_check();
|
||||
int upx_doctest_check();
|
||||
@@ -870,7 +883,7 @@ int do_files(int i, int argc, char *argv[]);
|
||||
|
||||
// help.cpp
|
||||
extern const char gitrev[];
|
||||
void show_head();
|
||||
void show_header();
|
||||
void show_help(int verbose=0);
|
||||
void show_license();
|
||||
void show_usage();
|
||||
@@ -898,6 +911,17 @@ int upx_test_overlap ( const upx_bytep buf,
|
||||
const upx_compress_result_t *cresult );
|
||||
|
||||
|
||||
#include "util/snprintf.h" // must get included first!
|
||||
#include "options.h"
|
||||
#include "except.h"
|
||||
#include "bele.h"
|
||||
#include "console/console.h"
|
||||
#include "util/util.h"
|
||||
// xspan
|
||||
#include "util/raw_bytes.h"
|
||||
#include "util/xspan.h"
|
||||
|
||||
|
||||
#if (ACC_OS_CYGWIN || ACC_OS_DOS16 || ACC_OS_DOS32 || ACC_OS_EMX || ACC_OS_OS2 || ACC_OS_OS216 || ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64)
|
||||
# if defined(INVALID_HANDLE_VALUE) || defined(MAKEWORD) || defined(RT_CURSOR)
|
||||
# error "something pulled in <windows.h>"
|
||||
|
||||
Reference in New Issue
Block a user