diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 943c8031..8daf0f52 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -99,9 +99,9 @@ jobs: - run: uname -a; pwd; id; umask - run: sudo apt-get update - run: sudo apt-get install -y dmidecode gdb parallel valgrind - - run: sudo dmidecode | sed -n -e '/System Information/,/^$/p' - - run: sudo dmidecode -q - - run: sudo dmidecode + - run: (sudo dmidecode | sed -n -e '/System Information/,/^$/p') || true + - run: sudo dmidecode -q || true + - run: sudo dmidecode || true - uses: actions/checkout@v4 with: { submodules: true } - run: make build/extra/gcc/all @@ -119,6 +119,11 @@ jobs: - name: ${{ format('Upload artifact {0}', env.artifact_name) }} uses: actions/upload-artifact@v4 with: { name: '${{ env.artifact_name }}', path: tmp/artifact } + - name: Run install tests + run: | + jobs="gcc/debug gcc/release clang/debug clang/release" + echo "===== parallel jobs: $jobs" + DESTDIR="Install with make 2" parallel -kv --lb 'make build/extra/{}+install' ::: $jobs - name: Mimic ctest tests SIGSEGV run: | jobs="gcc/debug gcc/release clang/debug clang/release" @@ -164,11 +169,11 @@ jobs: ls -l /usr/bin/${f}* done ls -l /etc/alternatives/*mingw* || true - - run: sudo dmidecode | sed -n -e '/System Information/,/^$/p' + - run: (sudo dmidecode | sed -n -e '/System Information/,/^$/p') || true if: ${{ matrix.use_extra }} - - run: sudo dmidecode -q + - run: sudo dmidecode -q || true if: ${{ matrix.use_extra }} - - run: sudo dmidecode + - run: sudo dmidecode || true if: ${{ matrix.use_extra }} - name: Install Wine if: ${{ matrix.use_extra && matrix.use_wine }} @@ -223,6 +228,10 @@ jobs: run: | (cd build/extra/gcc/release && DESTDIR="$PWD/Install with cmake" cmake --install .) (cd build/extra/gcc/release && DESTDIR="$PWD/Install with make" make install) + jobs="gcc/debug gcc/release clang/debug clang/release" + test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release" + echo "===== parallel jobs: $jobs" + DESTDIR="Install with make 2" parallel -kv --lb 'make build/extra/{}+install' ::: $jobs - name: Mimic ctest tests SIGSEGV run: | jobs="gcc/debug gcc/release clang/debug clang/release" @@ -571,7 +580,7 @@ jobs: # only build a few selected targets => more targets are tested in the Weekly CI - { zig_target: aarch64-linux-musl, qemu: qemu-aarch64 } - { zig_target: aarch64-linux-musl, qemu: qemu-aarch64, zig_pic: -fPIE, container: 'alpine:3.18' } - - { zig_target: aarch64-macos.11.0-none } + - { zig_target: aarch64-macos.13.0-none } - { zig_target: aarch64-windows-gnu } - { zig_target: arm-linux-musleabihf, qemu: qemu-arm } - { zig_target: armeb-linux-musleabihf, qemu: qemu-armeb } @@ -597,7 +606,7 @@ jobs: - { zig_target: x86_64-linux-gnu.2.17, qemu: qemu-x86_64 } # can use QEMU because of gcompat - { zig_target: x86_64-linux-musl, qemu: qemu-x86_64 } - { zig_target: x86_64-linux-musl, qemu: qemu-x86_64, zig_pic: -fPIE, container: 'alpine:3.18' } - - { zig_target: x86_64-macos.11.0-none } + - { zig_target: x86_64-macos.13.0-none } - { zig_target: x86_64-windows-gnu } name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }} runs-on: ubuntu-latest diff --git a/misc/scripts/run_cmake_config.sh b/misc/scripts/run_cmake_config.sh index ce1e2268..14d2bf58 100755 --- a/misc/scripts/run_cmake_config.sh +++ b/misc/scripts/run_cmake_config.sh @@ -14,7 +14,7 @@ __add_cmake_config() { } # pass common CMake settings -for v in CMAKE_VERBOSE_MAKEFILE; do +for v in CMAKE_INSTALL_PREFIX CMAKE_VERBOSE_MAKEFILE; do __add_cmake_config $v done # pass common CMake toolchain settings diff --git a/misc/scripts/upx-clang-format.sh b/misc/scripts/upx-clang-format.sh index 4a0f4981..1bd4c48e 100755 --- a/misc/scripts/upx-clang-format.sh +++ b/misc/scripts/upx-clang-format.sh @@ -29,6 +29,6 @@ fi # limit memory usage to 1 GiB (in case of clang-format problems with invalid files) ulimit -v 1048576 || true -#echo $UPX_CLANG_FORMAT +#echo "$UPX_CLANG_FORMAT" exec "$UPX_CLANG_FORMAT" -style=file "$@" exit 99 diff --git a/src/bele_policy.h b/src/bele_policy.h index b71ac8ad..186aa4df 100644 --- a/src/bele_policy.h +++ b/src/bele_policy.h @@ -210,7 +210,7 @@ private: UPX_CXX_DISABLE_NEW_DELETE(LEPolicy) }; -// Native Endianness policy (aka host policy) +// Native Endianness policy (aka Host Policy) #if (ACC_ABI_BIG_ENDIAN) typedef BEPolicy NEPolicy; typedef BEPolicy HostPolicy; diff --git a/src/except.h b/src/except.h index 318fd8c8..eb71d0ea 100644 --- a/src/except.h +++ b/src/except.h @@ -200,15 +200,15 @@ noreturn void throwEOFException(const char *msg = nullptr, int e = 0) may_throw; // some C++ template wizardry is needed to overload throwCantPack() for varargs template void throwCantPack(const T *, ...) DELETED_FUNCTION; -template <> -noreturn void throwCantPack(const char *format, ...) may_throw attribute_format(1, 2); template void throwCantUnpack(const T *, ...) DELETED_FUNCTION; -template <> -noreturn void throwCantUnpack(const char *format, ...) may_throw attribute_format(1, 2); template void throwInternalError(const T *, ...) DELETED_FUNCTION; template <> +noreturn void throwCantPack(const char *format, ...) may_throw attribute_format(1, 2); +template <> +noreturn void throwCantUnpack(const char *format, ...) may_throw attribute_format(1, 2); +template <> noreturn void throwInternalError(const char *format, ...) may_throw attribute_format(1, 2); /* vim:set ts=4 sw=4 et: */ diff --git a/src/packer.h b/src/packer.h index c703da13..1dd32aec 100644 --- a/src/packer.h +++ b/src/packer.h @@ -48,7 +48,7 @@ protected: public: virtual ~PackerBase() noexcept {} // getVersion() enables detecting forward incompatibility of unpack() - // by old upx when newer upx changes the format of compressed output. + // by old UPX when newer UPX changes the format of compressed output. virtual int getVersion() const = 0; // A unique integer ID for this executable format; see UPX_F_xxx in conf.h. virtual int getFormat() const = 0; @@ -58,11 +58,11 @@ public: virtual const int *getFilters() const = 0; // canPack() should throw a cantPackException explaining why it cannot pack - // a recognized format. + // a recognized format. // canPack() can also return -1 to fail early; see class PackMaster virtual tribool canPack() = 0; // canUnpack() should throw a cantUnpackException explaining why it cannot unpack - // a recognized format. + // a recognized format. // canUnpack() can also return -1 to fail early; see class PackMaster virtual tribool canUnpack() = 0; diff --git a/src/stub/Makefile b/src/stub/Makefile index 208a55ec..f4984f70 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -552,6 +552,7 @@ amd64-win64.pe.h : tc_objdump_disasm_options = -M intel-mnemonic tc.amd64-win64.pe.gcc = amd64-linux-gcc-4.1.1 -m64 -nostdinc -DWINDOWS_BACK=1 -MMD -MT $@ tc.amd64-win64.pe.gcc += -fno-exceptions -fno-asynchronous-unwind-tables +tc.amd64-win64.pe.gcc += -mno-red-zone tc.amd64-win64.pe.gcc += -Wall -W -Wcast-align -Wcast-qual -Wstrict-prototypes -Wwrite-strings -Werror tc.amd64-win64.pe.objdump = multiarch-objdump-2.23.90 diff --git a/src/util/cxxlib.h b/src/util/cxxlib.h index 3a465e86..a95a215b 100644 --- a/src/util/cxxlib.h +++ b/src/util/cxxlib.h @@ -33,6 +33,222 @@ namespace upx { +/************************************************************************* +// compile_time +**************************************************************************/ + +namespace compile_time { + +constexpr std::size_t string_len(const char *a) noexcept { + return *a == '\0' ? 0 : 1 + string_len(a + 1); +} +constexpr bool string_eq(const char *a, const char *b) noexcept { + return *a == *b && (*a == '\0' || string_eq(a + 1, b + 1)); +} +constexpr bool string_lt(const char *a, const char *b) noexcept { + return (uchar) *a < (uchar) *b || (*a != '\0' && *a == *b && string_lt(a + 1, b + 1)); +} +forceinline constexpr bool string_ne(const char *a, const char *b) noexcept { + return !string_eq(a, b); +} +forceinline constexpr bool string_gt(const char *a, const char *b) noexcept { + return string_lt(b, a); +} +forceinline constexpr bool string_le(const char *a, const char *b) noexcept { + return !string_lt(b, a); +} +forceinline constexpr bool string_ge(const char *a, const char *b) noexcept { + return !string_lt(a, b); +} + +constexpr bool mem_eq(const char *a, const char *b, std::size_t n) noexcept { + return n == 0 || (*a == *b && mem_eq(a + 1, b + 1, n - 1)); +} +constexpr bool mem_eq(const unsigned char *a, const unsigned char *b, std::size_t n) noexcept { + return n == 0 || (*a == *b && mem_eq(a + 1, b + 1, n - 1)); +} +constexpr bool mem_eq(const char *a, const unsigned char *b, std::size_t n) noexcept { + return n == 0 || ((uchar) *a == *b && mem_eq(a + 1, b + 1, n - 1)); +} +constexpr bool mem_eq(const unsigned char *a, const char *b, std::size_t n) noexcept { + return n == 0 || (*a == (uchar) *b && mem_eq(a + 1, b + 1, n - 1)); +} + +constexpr void mem_set(char *p, char c, std::size_t n) noexcept { + (void) (n == 0 || (*p = c, mem_set(p + 1, c, n - 1), 0)); +} +constexpr void mem_set(unsigned char *p, unsigned char c, std::size_t n) noexcept { + (void) (n == 0 || (*p = c, mem_set(p + 1, c, n - 1), 0)); +} +forceinline constexpr void mem_clear(char *p, std::size_t n) noexcept { mem_set(p, (char) 0, n); } +forceinline constexpr void mem_clear(unsigned char *p, std::size_t n) noexcept { + mem_set(p, (unsigned char) 0, n); +} + +forceinline constexpr upx_uint16_t bswap16(upx_uint16_t v) noexcept { + typedef unsigned U; + return (upx_uint16_t) ((((U) v >> 8) & 0xff) | (((U) v & 0xff) << 8)); +} +forceinline constexpr upx_uint32_t bswap32(upx_uint32_t v) noexcept { + typedef upx_uint32_t U; + return (upx_uint32_t) ((((U) v >> 24) & 0xff) | (((U) v >> 8) & 0xff00) | + (((U) v & 0xff00) << 8) | (((U) v & 0xff) << 24)); +} +forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) noexcept { + return (upx_uint64_t) (((upx_uint64_t) bswap32((upx_uint32_t) v) << 32) | + bswap32((upx_uint32_t) (v >> 32))); +} + +forceinline constexpr upx_uint16_t get_be16(const byte *p) noexcept { + typedef unsigned U; + return (upx_uint16_t) (((U) p[0] << 8) | ((U) p[1] << 0)); +} +forceinline constexpr upx_uint32_t get_be24(const byte *p) noexcept { + typedef upx_uint32_t U; + return (upx_uint32_t) (((U) p[0] << 16) | ((U) p[1] << 8) | ((U) p[2] << 0)); +} +forceinline constexpr upx_uint32_t get_be32(const byte *p) noexcept { + typedef upx_uint32_t U; + return (upx_uint32_t) (((U) p[0] << 24) | ((U) p[1] << 16) | ((U) p[2] << 8) | ((U) p[3] << 0)); +} +forceinline constexpr upx_uint64_t get_be64(const byte *p) noexcept { + typedef upx_uint64_t U; + return (upx_uint64_t) (((U) p[0] << 56) | ((U) p[1] << 48) | ((U) p[2] << 40) | + ((U) p[3] << 32) | ((U) p[4] << 24) | ((U) p[5] << 16) | + ((U) p[6] << 8) | ((U) p[7] << 0)); +} + +forceinline constexpr void set_be16(byte *p, upx_uint16_t v) noexcept { + p[0] = (byte) ((v >> 8) & 0xff); + p[1] = (byte) ((v >> 0) & 0xff); +} +forceinline constexpr void set_be24(byte *p, upx_uint32_t v) noexcept { + p[0] = (byte) ((v >> 16) & 0xff); + p[1] = (byte) ((v >> 8) & 0xff); + p[2] = (byte) ((v >> 0) & 0xff); +} +forceinline constexpr void set_be32(byte *p, upx_uint32_t v) noexcept { + p[0] = (byte) ((v >> 24) & 0xff); + p[1] = (byte) ((v >> 16) & 0xff); + p[2] = (byte) ((v >> 8) & 0xff); + p[3] = (byte) ((v >> 0) & 0xff); +} +forceinline constexpr void set_be64(byte *p, upx_uint64_t v) noexcept { + p[0] = (byte) ((v >> 56) & 0xff); + p[1] = (byte) ((v >> 48) & 0xff); + p[2] = (byte) ((v >> 40) & 0xff); + p[3] = (byte) ((v >> 32) & 0xff); + p[4] = (byte) ((v >> 24) & 0xff); + p[5] = (byte) ((v >> 16) & 0xff); + p[6] = (byte) ((v >> 8) & 0xff); + p[7] = (byte) ((v >> 0) & 0xff); +} + +forceinline constexpr upx_uint16_t get_le16(const byte *p) noexcept { + typedef unsigned U; + return (upx_uint16_t) (((U) p[0] << 0) | ((U) p[1] << 8)); +} +forceinline constexpr upx_uint32_t get_le24(const byte *p) noexcept { + typedef upx_uint32_t U; + return (upx_uint32_t) (((U) p[0] << 0) | ((U) p[1] << 8) | ((U) p[2] << 16)); +} +forceinline constexpr upx_uint32_t get_le32(const byte *p) noexcept { + typedef upx_uint32_t U; + return (upx_uint32_t) (((U) p[0] << 0) | ((U) p[1] << 8) | ((U) p[2] << 16) | ((U) p[3] << 24)); +} +forceinline constexpr upx_uint64_t get_le64(const byte *p) noexcept { + typedef upx_uint64_t U; + return (upx_uint64_t) (((U) p[0] << 0) | ((U) p[1] << 8) | ((U) p[2] << 16) | ((U) p[3] << 24) | + ((U) p[4] << 32) | ((U) p[5] << 40) | ((U) p[6] << 48) | + ((U) p[7] << 56)); +} + +forceinline constexpr void set_le16(byte *p, upx_uint16_t v) noexcept { + p[0] = (byte) ((v >> 0) & 0xff); + p[1] = (byte) ((v >> 8) & 0xff); +} +forceinline constexpr void set_le24(byte *p, upx_uint32_t v) noexcept { + p[0] = (byte) ((v >> 0) & 0xff); + p[1] = (byte) ((v >> 8) & 0xff); + p[2] = (byte) ((v >> 16) & 0xff); +} +forceinline constexpr void set_le32(byte *p, upx_uint32_t v) noexcept { + p[0] = (byte) ((v >> 0) & 0xff); + p[1] = (byte) ((v >> 8) & 0xff); + p[2] = (byte) ((v >> 16) & 0xff); + p[3] = (byte) ((v >> 24) & 0xff); +} +forceinline constexpr void set_le64(byte *p, upx_uint64_t v) noexcept { + p[0] = (byte) ((v >> 0) & 0xff); + p[1] = (byte) ((v >> 8) & 0xff); + p[2] = (byte) ((v >> 16) & 0xff); + p[3] = (byte) ((v >> 24) & 0xff); + p[4] = (byte) ((v >> 32) & 0xff); + p[5] = (byte) ((v >> 40) & 0xff); + p[6] = (byte) ((v >> 48) & 0xff); + p[7] = (byte) ((v >> 56) & 0xff); +} + +forceinline constexpr upx_uint16_t get_ne16(const byte *p) noexcept { +#if (ACC_ABI_BIG_ENDIAN) + return get_be16(p); +#else + return get_le16(p); +#endif +} +forceinline constexpr upx_uint32_t get_ne24(const byte *p) noexcept { +#if (ACC_ABI_BIG_ENDIAN) + return get_be24(p); +#else + return get_le24(p); +#endif +} +forceinline constexpr upx_uint32_t get_ne32(const byte *p) noexcept { +#if (ACC_ABI_BIG_ENDIAN) + return get_be32(p); +#else + return get_le32(p); +#endif +} +forceinline constexpr upx_uint64_t get_ne64(const byte *p) noexcept { +#if (ACC_ABI_BIG_ENDIAN) + return get_be64(p); +#else + return get_le64(p); +#endif +} + +forceinline constexpr void set_ne16(byte *p, upx_uint16_t v) noexcept { +#if (ACC_ABI_BIG_ENDIAN) + set_be16(p, v); +#else + set_le16(p, v); +#endif +} +forceinline constexpr void set_ne24(byte *p, upx_uint32_t v) noexcept { +#if (ACC_ABI_BIG_ENDIAN) + set_be24(p, v); +#else + set_le24(p, v); +#endif +} +forceinline constexpr void set_ne32(byte *p, upx_uint32_t v) noexcept { +#if (ACC_ABI_BIG_ENDIAN) + set_be32(p, v); +#else + set_le32(p, v); +#endif +} +forceinline constexpr void set_ne64(byte *p, upx_uint64_t v) noexcept { +#if (ACC_ABI_BIG_ENDIAN) + set_be64(p, v); +#else + set_le64(p, v); +#endif +} + +} // namespace compile_time + /************************************************************************* // core util **************************************************************************/ @@ -340,6 +556,7 @@ forceinline T atomic_exchange(T *ptr, T new_value) noexcept { // helper classes so we don't leak memory on exceptions template struct ObjectDeleter final { + static_assert(std::is_nothrow_destructible_v); T **items; // public std::size_t count; // public explicit ObjectDeleter(T **p, std::size_t n) noexcept : items(p), count(n) {} @@ -350,10 +567,10 @@ struct ObjectDeleter final { delete item; // single object delete } } - static_assert(std::is_nothrow_destructible_v); }; template struct ArrayDeleter final { + static_assert(std::is_nothrow_destructible_v); T **items; // public std::size_t count; // public explicit ArrayDeleter(T **p, std::size_t n) noexcept : items(p), count(n) {} @@ -364,7 +581,6 @@ struct ArrayDeleter final { delete[] item; // array delete } } - static_assert(std::is_nothrow_destructible_v); }; template struct MallocDeleter final { @@ -380,222 +596,6 @@ struct MallocDeleter final { } }; -/************************************************************************* -// compile_time -**************************************************************************/ - -namespace compile_time { - -constexpr std::size_t string_len(const char *a) noexcept { - return *a == '\0' ? 0 : 1 + string_len(a + 1); -} -constexpr bool string_eq(const char *a, const char *b) noexcept { - return *a == *b && (*a == '\0' || string_eq(a + 1, b + 1)); -} -constexpr bool string_lt(const char *a, const char *b) noexcept { - return (uchar) *a < (uchar) *b || (*a != '\0' && *a == *b && string_lt(a + 1, b + 1)); -} -forceinline constexpr bool string_ne(const char *a, const char *b) noexcept { - return !string_eq(a, b); -} -forceinline constexpr bool string_gt(const char *a, const char *b) noexcept { - return string_lt(b, a); -} -forceinline constexpr bool string_le(const char *a, const char *b) noexcept { - return !string_lt(b, a); -} -forceinline constexpr bool string_ge(const char *a, const char *b) noexcept { - return !string_lt(a, b); -} - -constexpr bool mem_eq(const char *a, const char *b, std::size_t n) noexcept { - return n == 0 || (*a == *b && mem_eq(a + 1, b + 1, n - 1)); -} -constexpr bool mem_eq(const unsigned char *a, const unsigned char *b, std::size_t n) noexcept { - return n == 0 || (*a == *b && mem_eq(a + 1, b + 1, n - 1)); -} -constexpr bool mem_eq(const char *a, const unsigned char *b, std::size_t n) noexcept { - return n == 0 || ((uchar) *a == *b && mem_eq(a + 1, b + 1, n - 1)); -} -constexpr bool mem_eq(const unsigned char *a, const char *b, std::size_t n) noexcept { - return n == 0 || (*a == (uchar) *b && mem_eq(a + 1, b + 1, n - 1)); -} - -constexpr void mem_set(char *p, char c, std::size_t n) noexcept { - (void) (n == 0 || (*p = c, mem_set(p + 1, c, n - 1), 0)); -} -constexpr void mem_set(unsigned char *p, unsigned char c, std::size_t n) noexcept { - (void) (n == 0 || (*p = c, mem_set(p + 1, c, n - 1), 0)); -} -forceinline constexpr void mem_clear(char *p, std::size_t n) noexcept { mem_set(p, (char) 0, n); } -forceinline constexpr void mem_clear(unsigned char *p, std::size_t n) noexcept { - mem_set(p, (unsigned char) 0, n); -} - -forceinline constexpr upx_uint16_t bswap16(upx_uint16_t v) noexcept { - typedef unsigned U; - return (upx_uint16_t) ((((U) v >> 8) & 0xff) | (((U) v & 0xff) << 8)); -} -forceinline constexpr upx_uint32_t bswap32(upx_uint32_t v) noexcept { - typedef upx_uint32_t U; - return (upx_uint32_t) ((((U) v >> 24) & 0xff) | (((U) v >> 8) & 0xff00) | - (((U) v & 0xff00) << 8) | (((U) v & 0xff) << 24)); -} -forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) noexcept { - return (upx_uint64_t) (((upx_uint64_t) bswap32((upx_uint32_t) v) << 32) | - bswap32((upx_uint32_t) (v >> 32))); -} - -forceinline constexpr upx_uint16_t get_be16(const byte *p) noexcept { - typedef unsigned U; - return (upx_uint16_t) (((U) p[0] << 8) | ((U) p[1] << 0)); -} -forceinline constexpr upx_uint32_t get_be24(const byte *p) noexcept { - typedef upx_uint32_t U; - return (upx_uint32_t) (((U) p[0] << 16) | ((U) p[1] << 8) | ((U) p[2] << 0)); -} -forceinline constexpr upx_uint32_t get_be32(const byte *p) noexcept { - typedef upx_uint32_t U; - return (upx_uint32_t) (((U) p[0] << 24) | ((U) p[1] << 16) | ((U) p[2] << 8) | ((U) p[3] << 0)); -} -forceinline constexpr upx_uint64_t get_be64(const byte *p) noexcept { - typedef upx_uint64_t U; - return (upx_uint64_t) (((U) p[0] << 56) | ((U) p[1] << 48) | ((U) p[2] << 40) | - ((U) p[3] << 32) | ((U) p[4] << 24) | ((U) p[5] << 16) | - ((U) p[6] << 8) | ((U) p[7] << 0)); -} - -forceinline constexpr void set_be16(byte *p, upx_uint16_t v) noexcept { - p[0] = (byte) ((v >> 8) & 0xff); - p[1] = (byte) ((v >> 0) & 0xff); -} -forceinline constexpr void set_be24(byte *p, upx_uint32_t v) noexcept { - p[0] = (byte) ((v >> 16) & 0xff); - p[1] = (byte) ((v >> 8) & 0xff); - p[2] = (byte) ((v >> 0) & 0xff); -} -forceinline constexpr void set_be32(byte *p, upx_uint32_t v) noexcept { - p[0] = (byte) ((v >> 24) & 0xff); - p[1] = (byte) ((v >> 16) & 0xff); - p[2] = (byte) ((v >> 8) & 0xff); - p[3] = (byte) ((v >> 0) & 0xff); -} -forceinline constexpr void set_be64(byte *p, upx_uint64_t v) noexcept { - p[0] = (byte) ((v >> 56) & 0xff); - p[1] = (byte) ((v >> 48) & 0xff); - p[2] = (byte) ((v >> 40) & 0xff); - p[3] = (byte) ((v >> 32) & 0xff); - p[4] = (byte) ((v >> 24) & 0xff); - p[5] = (byte) ((v >> 16) & 0xff); - p[6] = (byte) ((v >> 8) & 0xff); - p[7] = (byte) ((v >> 0) & 0xff); -} - -forceinline constexpr upx_uint16_t get_le16(const byte *p) noexcept { - typedef unsigned U; - return (upx_uint16_t) (((U) p[0] << 0) | ((U) p[1] << 8)); -} -forceinline constexpr upx_uint32_t get_le24(const byte *p) noexcept { - typedef upx_uint32_t U; - return (upx_uint32_t) (((U) p[0] << 0) | ((U) p[1] << 8) | ((U) p[2] << 16)); -} -forceinline constexpr upx_uint32_t get_le32(const byte *p) noexcept { - typedef upx_uint32_t U; - return (upx_uint32_t) (((U) p[0] << 0) | ((U) p[1] << 8) | ((U) p[2] << 16) | ((U) p[3] << 24)); -} -forceinline constexpr upx_uint64_t get_le64(const byte *p) noexcept { - typedef upx_uint64_t U; - return (upx_uint64_t) (((U) p[0] << 0) | ((U) p[1] << 8) | ((U) p[2] << 16) | ((U) p[3] << 24) | - ((U) p[4] << 32) | ((U) p[5] << 40) | ((U) p[6] << 48) | - ((U) p[7] << 56)); -} - -forceinline constexpr void set_le16(byte *p, upx_uint16_t v) noexcept { - p[0] = (byte) ((v >> 0) & 0xff); - p[1] = (byte) ((v >> 8) & 0xff); -} -forceinline constexpr void set_le24(byte *p, upx_uint32_t v) noexcept { - p[0] = (byte) ((v >> 0) & 0xff); - p[1] = (byte) ((v >> 8) & 0xff); - p[2] = (byte) ((v >> 16) & 0xff); -} -forceinline constexpr void set_le32(byte *p, upx_uint32_t v) noexcept { - p[0] = (byte) ((v >> 0) & 0xff); - p[1] = (byte) ((v >> 8) & 0xff); - p[2] = (byte) ((v >> 16) & 0xff); - p[3] = (byte) ((v >> 24) & 0xff); -} -forceinline constexpr void set_le64(byte *p, upx_uint64_t v) noexcept { - p[0] = (byte) ((v >> 0) & 0xff); - p[1] = (byte) ((v >> 8) & 0xff); - p[2] = (byte) ((v >> 16) & 0xff); - p[3] = (byte) ((v >> 24) & 0xff); - p[4] = (byte) ((v >> 32) & 0xff); - p[5] = (byte) ((v >> 40) & 0xff); - p[6] = (byte) ((v >> 48) & 0xff); - p[7] = (byte) ((v >> 56) & 0xff); -} - -forceinline constexpr upx_uint16_t get_ne16(const byte *p) noexcept { -#if (ACC_ABI_BIG_ENDIAN) - return get_be16(p); -#else - return get_le16(p); -#endif -} -forceinline constexpr upx_uint32_t get_ne24(const byte *p) noexcept { -#if (ACC_ABI_BIG_ENDIAN) - return get_be24(p); -#else - return get_le24(p); -#endif -} -forceinline constexpr upx_uint32_t get_ne32(const byte *p) noexcept { -#if (ACC_ABI_BIG_ENDIAN) - return get_be32(p); -#else - return get_le32(p); -#endif -} -forceinline constexpr upx_uint64_t get_ne64(const byte *p) noexcept { -#if (ACC_ABI_BIG_ENDIAN) - return get_be64(p); -#else - return get_le64(p); -#endif -} - -forceinline constexpr void set_ne16(byte *p, upx_uint16_t v) noexcept { -#if (ACC_ABI_BIG_ENDIAN) - set_be16(p, v); -#else - set_le16(p, v); -#endif -} -forceinline constexpr void set_ne24(byte *p, upx_uint32_t v) noexcept { -#if (ACC_ABI_BIG_ENDIAN) - set_be24(p, v); -#else - set_le24(p, v); -#endif -} -forceinline constexpr void set_ne32(byte *p, upx_uint32_t v) noexcept { -#if (ACC_ABI_BIG_ENDIAN) - set_be32(p, v); -#else - set_le32(p, v); -#endif -} -forceinline constexpr void set_ne64(byte *p, upx_uint64_t v) noexcept { -#if (ACC_ABI_BIG_ENDIAN) - set_be64(p, v); -#else - set_le64(p, v); -#endif -} - -} // namespace compile_time - /************************************************************************* // TriBool - tri-state bool // an enum with an underlying type and 3 values diff --git a/src/util/xspan_impl.h b/src/util/xspan_impl.h index c359d221..bd92aa1f 100644 --- a/src/util/xspan_impl.h +++ b/src/util/xspan_impl.h @@ -225,6 +225,7 @@ XSPAN_NAMESPACE_END #ifndef XSPAN_DELETED_FUNCTION #define XSPAN_DELETED_FUNCTION = delete #endif + // function/method constraints #define XSPAN_REQUIRES_CONVERTIBLE_ONE_DIRECTION(From, To, RType) \ typename std::enable_if::value, RType > ::type @@ -250,6 +251,7 @@ XSPAN_NAMESPACE_END #include "xspan_impl_ptr_or_span.h" #include "xspan_impl_span.h" #include "xspan_impl_ptr.h" + #undef XSPAN_REQUIRES_CONVERTIBLE_ONE_DIRECTION #undef XSPAN_REQUIRES_CONVERTIBLE_ANY_DIRECTION #undef XSPAN_REQUIRES_CONVERTIBLE_A