src: introduce upx::max and friends; updates for clang-19 git snapshot
This commit is contained in:
+29
-27
@@ -750,40 +750,42 @@ template <class T>
|
|||||||
T *operator+(const LE64 &v, T *ptr) noexcept DELETED_FUNCTION;
|
T *operator+(const LE64 &v, T *ptr) noexcept DELETED_FUNCTION;
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// global overloads
|
// some global overloads
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
// TODO later: move these to upx namespace in util/cxxlib.h; see conf.h
|
namespace upx {
|
||||||
inline unsigned ALIGN_DOWN(unsigned a, const BE32 &b) { return ALIGN_DOWN(a, unsigned(b)); }
|
|
||||||
inline unsigned ALIGN_DOWN(const BE32 &a, unsigned b) { return ALIGN_DOWN(unsigned(a), b); }
|
|
||||||
inline unsigned ALIGN_UP(unsigned a, const BE32 &b) { return ALIGN_UP(a, unsigned(b)); }
|
|
||||||
inline unsigned ALIGN_UP(const BE32 &a, unsigned b) { return ALIGN_UP(unsigned(a), b); }
|
|
||||||
|
|
||||||
inline unsigned ALIGN_DOWN(unsigned a, const LE32 &b) { return ALIGN_DOWN(a, unsigned(b)); }
|
inline unsigned align_down(unsigned a, const BE32 &b) { return align_down(a, unsigned(b)); }
|
||||||
inline unsigned ALIGN_DOWN(const LE32 &a, unsigned b) { return ALIGN_DOWN(unsigned(a), b); }
|
inline unsigned align_down(const BE32 &a, unsigned b) { return align_down(unsigned(a), b); }
|
||||||
inline unsigned ALIGN_UP(unsigned a, const LE32 &b) { return ALIGN_UP(a, unsigned(b)); }
|
inline unsigned align_up(unsigned a, const BE32 &b) { return align_up(a, unsigned(b)); }
|
||||||
inline unsigned ALIGN_UP(const LE32 &a, unsigned b) { return ALIGN_UP(unsigned(a), b); }
|
inline unsigned align_up(const BE32 &a, unsigned b) { return align_up(unsigned(a), b); }
|
||||||
|
|
||||||
// TODO later: introduce upx::umax() and upx::umin()
|
inline unsigned align_down(unsigned a, const LE32 &b) { return align_down(a, unsigned(b)); }
|
||||||
inline unsigned UPX_MAX(unsigned a, const BE16 &b) { return UPX_MAX(a, unsigned(b)); }
|
inline unsigned align_down(const LE32 &a, unsigned b) { return align_down(unsigned(a), b); }
|
||||||
inline unsigned UPX_MAX(const BE16 &a, unsigned b) { return UPX_MAX(unsigned(a), b); }
|
inline unsigned align_up(unsigned a, const LE32 &b) { return align_up(a, unsigned(b)); }
|
||||||
inline unsigned UPX_MIN(unsigned a, const BE16 &b) { return UPX_MIN(a, unsigned(b)); }
|
inline unsigned align_up(const LE32 &a, unsigned b) { return align_up(unsigned(a), b); }
|
||||||
inline unsigned UPX_MIN(const BE16 &a, unsigned b) { return UPX_MIN(unsigned(a), b); }
|
|
||||||
|
|
||||||
inline unsigned UPX_MAX(unsigned a, const BE32 &b) { return UPX_MAX(a, unsigned(b)); }
|
inline unsigned max(unsigned a, const BE16 &b) { return max(a, unsigned(b)); }
|
||||||
inline unsigned UPX_MAX(const BE32 &a, unsigned b) { return UPX_MAX(unsigned(a), b); }
|
inline unsigned max(const BE16 &a, unsigned b) { return max(unsigned(a), b); }
|
||||||
inline unsigned UPX_MIN(unsigned a, const BE32 &b) { return UPX_MIN(a, unsigned(b)); }
|
inline unsigned min(unsigned a, const BE16 &b) { return min(a, unsigned(b)); }
|
||||||
inline unsigned UPX_MIN(const BE32 &a, unsigned b) { return UPX_MIN(unsigned(a), b); }
|
inline unsigned min(const BE16 &a, unsigned b) { return min(unsigned(a), b); }
|
||||||
|
|
||||||
inline unsigned UPX_MAX(unsigned a, const LE16 &b) { return UPX_MAX(a, unsigned(b)); }
|
inline unsigned max(unsigned a, const BE32 &b) { return max(a, unsigned(b)); }
|
||||||
inline unsigned UPX_MAX(const LE16 &a, unsigned b) { return UPX_MAX(unsigned(a), b); }
|
inline unsigned max(const BE32 &a, unsigned b) { return max(unsigned(a), b); }
|
||||||
inline unsigned UPX_MIN(unsigned a, const LE16 &b) { return UPX_MIN(a, unsigned(b)); }
|
inline unsigned min(unsigned a, const BE32 &b) { return min(a, unsigned(b)); }
|
||||||
inline unsigned UPX_MIN(const LE16 &a, unsigned b) { return UPX_MIN(unsigned(a), b); }
|
inline unsigned min(const BE32 &a, unsigned b) { return min(unsigned(a), b); }
|
||||||
|
|
||||||
inline unsigned UPX_MAX(unsigned a, const LE32 &b) { return UPX_MAX(a, unsigned(b)); }
|
inline unsigned max(unsigned a, const LE16 &b) { return max(a, unsigned(b)); }
|
||||||
inline unsigned UPX_MAX(const LE32 &a, unsigned b) { return UPX_MAX(unsigned(a), b); }
|
inline unsigned max(const LE16 &a, unsigned b) { return max(unsigned(a), b); }
|
||||||
inline unsigned UPX_MIN(unsigned a, const LE32 &b) { return UPX_MIN(a, unsigned(b)); }
|
inline unsigned min(unsigned a, const LE16 &b) { return min(a, unsigned(b)); }
|
||||||
inline unsigned UPX_MIN(const LE32 &a, unsigned b) { return UPX_MIN(unsigned(a), b); }
|
inline unsigned min(const LE16 &a, unsigned b) { return min(unsigned(a), b); }
|
||||||
|
|
||||||
|
inline unsigned max(unsigned a, const LE32 &b) { return max(a, unsigned(b)); }
|
||||||
|
inline unsigned max(const LE32 &a, unsigned b) { return max(unsigned(a), b); }
|
||||||
|
inline unsigned min(unsigned a, const LE32 &b) { return min(a, unsigned(b)); }
|
||||||
|
inline unsigned min(const LE32 &a, unsigned b) { return min(unsigned(a), b); }
|
||||||
|
|
||||||
|
} // namespace upx
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// misc support
|
// misc support
|
||||||
|
|||||||
@@ -230,6 +230,43 @@ struct CheckIntegral {
|
|||||||
}
|
}
|
||||||
checkU<T>();
|
checkU<T>();
|
||||||
checkU<typename std::add_const<T>::type>();
|
checkU<typename std::add_const<T>::type>();
|
||||||
|
{
|
||||||
|
T zero, one, three, four;
|
||||||
|
zero = 0;
|
||||||
|
one = 1;
|
||||||
|
three = 3;
|
||||||
|
four = 4;
|
||||||
|
// min / max
|
||||||
|
assert_noexcept(upx::min(one, four) == 1);
|
||||||
|
assert_noexcept(upx::min(one, four) == one);
|
||||||
|
assert_noexcept(upx::max(one, four) == 4);
|
||||||
|
assert_noexcept(upx::max(one, four) == four);
|
||||||
|
// align
|
||||||
|
assert_noexcept(upx::align_down(zero, four) == 0);
|
||||||
|
assert_noexcept(upx::align_down(zero, four) == zero);
|
||||||
|
assert_noexcept(upx::align_down(one, four) == 0);
|
||||||
|
assert_noexcept(upx::align_down(one, four) == zero);
|
||||||
|
assert_noexcept(upx::align_down(three, four) == 0);
|
||||||
|
assert_noexcept(upx::align_down(three, four) == zero);
|
||||||
|
assert_noexcept(upx::align_down(four, four) == 4);
|
||||||
|
assert_noexcept(upx::align_down(four, four) == four);
|
||||||
|
assert_noexcept(upx::align_up(zero, four) == 0);
|
||||||
|
assert_noexcept(upx::align_up(zero, four) == zero);
|
||||||
|
assert_noexcept(upx::align_up(one, four) == 4);
|
||||||
|
assert_noexcept(upx::align_up(one, four) == four);
|
||||||
|
assert_noexcept(upx::align_up(three, four) == 4);
|
||||||
|
assert_noexcept(upx::align_up(three, four) == four);
|
||||||
|
assert_noexcept(upx::align_up(four, four) == 4);
|
||||||
|
assert_noexcept(upx::align_up(four, four) == four);
|
||||||
|
assert_noexcept(upx::align_gap(zero, four) == 0);
|
||||||
|
assert_noexcept(upx::align_gap(zero, four) == zero);
|
||||||
|
assert_noexcept(upx::align_gap(one, four) == 3);
|
||||||
|
assert_noexcept(upx::align_gap(one, four) == three);
|
||||||
|
assert_noexcept(upx::align_gap(three, four) == 1);
|
||||||
|
assert_noexcept(upx::align_gap(three, four) == one);
|
||||||
|
assert_noexcept(upx::align_gap(four, four) == 0);
|
||||||
|
assert_noexcept(upx::align_gap(four, four) == zero);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+33
-3
@@ -122,10 +122,10 @@ TEST_CASE("std::vector") {
|
|||||||
CHECK(v.end() - v.begin() == N);
|
CHECK(v.end() - v.begin() == N);
|
||||||
CHECK(&v[0] == &(*(v.begin())));
|
CHECK(&v[0] == &(*(v.begin())));
|
||||||
// CHECK(&v[0] + N == &(*(v.end()))); // TODO later: is this legal??
|
// CHECK(&v[0] + N == &(*(v.end()))); // TODO later: is this legal??
|
||||||
// TODO later: make sure that this throws
|
#if defined(_LIBCPP_HARDENING_MODE) && defined(_LIBCPP_HARDENING_MODE_DEBUG) && \
|
||||||
#if defined(_LIBCPP_HARDENING_MODE_DEBUG) && \
|
|
||||||
(_LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG)
|
(_LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG)
|
||||||
CHECK_THROWS((void) &v[N]);
|
// unfortunately this does not throw but aborts
|
||||||
|
////CHECK_THROWS((void) &v[N]);
|
||||||
#endif
|
#endif
|
||||||
UNUSED(v);
|
UNUSED(v);
|
||||||
}
|
}
|
||||||
@@ -251,6 +251,36 @@ struct Z2_X2 : public X2 {
|
|||||||
// util
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("upx::min_max") {
|
||||||
|
static_assert(upx::min(0, 0) == 0);
|
||||||
|
static_assert(upx::min(0, 1) == 0);
|
||||||
|
static_assert(upx::min(1, 0) == 0);
|
||||||
|
static_assert(upx::max(0, 0) == 0);
|
||||||
|
static_assert(upx::max(0, 1) == 1);
|
||||||
|
static_assert(upx::max(1, 0) == 1);
|
||||||
|
static_assert(upx::umin(0u, 0u) == 0u);
|
||||||
|
static_assert(upx::umin(0u, 1u) == 0u);
|
||||||
|
static_assert(upx::umin(1u, 0u) == 0u);
|
||||||
|
static_assert(upx::umax(0u, 0u) == 0u);
|
||||||
|
static_assert(upx::umax(0u, 1u) == 1u);
|
||||||
|
static_assert(upx::umax(1u, 0u) == 1u);
|
||||||
|
CHECK_EQ(upx::align_down(0, 4), 0);
|
||||||
|
CHECK_EQ(upx::align_down(1, 4), 0);
|
||||||
|
CHECK_EQ(upx::align_down(2, 4), 0);
|
||||||
|
CHECK_EQ(upx::align_down(3, 4), 0);
|
||||||
|
CHECK_EQ(upx::align_down(4, 4), 4);
|
||||||
|
CHECK_EQ(upx::align_up(0, 4), 0);
|
||||||
|
CHECK_EQ(upx::align_up(1, 4), 4);
|
||||||
|
CHECK_EQ(upx::align_up(2, 4), 4);
|
||||||
|
CHECK_EQ(upx::align_up(3, 4), 4);
|
||||||
|
CHECK_EQ(upx::align_up(4, 4), 4);
|
||||||
|
CHECK_EQ(upx::align_gap(0, 4), 0);
|
||||||
|
CHECK_EQ(upx::align_gap(1, 4), 3);
|
||||||
|
CHECK_EQ(upx::align_gap(2, 4), 2);
|
||||||
|
CHECK_EQ(upx::align_gap(3, 4), 1);
|
||||||
|
CHECK_EQ(upx::align_gap(4, 4), 0);
|
||||||
|
}
|
||||||
|
|
||||||
#if WITH_THREADS
|
#if WITH_THREADS
|
||||||
TEST_CASE("upx::ptr_std_atomic_cast") {
|
TEST_CASE("upx::ptr_std_atomic_cast") {
|
||||||
// pointer-size
|
// pointer-size
|
||||||
|
|||||||
@@ -25,13 +25,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../conf.h"
|
#include "../conf.h"
|
||||||
#include "compress.h"
|
|
||||||
#include "../util/membuffer.h"
|
|
||||||
// NOLINTBEGIN(clang-analyzer-optin.performance.Padding)
|
|
||||||
#define ZLIB_CONST 1
|
|
||||||
#include <zlib/zlib.h>
|
|
||||||
#include <zlib/deflate.h>
|
|
||||||
// NOLINTEND(clang-analyzer-optin.performance.Padding)
|
|
||||||
|
|
||||||
void zlib_compress_config_t::reset() noexcept {
|
void zlib_compress_config_t::reset() noexcept {
|
||||||
mem_clear(this);
|
mem_clear(this);
|
||||||
@@ -40,6 +33,15 @@ void zlib_compress_config_t::reset() noexcept {
|
|||||||
strategy.reset();
|
strategy.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WITH_ZLIB
|
||||||
|
#include "compress.h"
|
||||||
|
#include "../util/membuffer.h"
|
||||||
|
// NOLINTBEGIN(clang-analyzer-optin.performance.Padding)
|
||||||
|
#define ZLIB_CONST 1
|
||||||
|
#include <zlib/zlib.h>
|
||||||
|
#include <zlib/deflate.h>
|
||||||
|
// NOLINTEND(clang-analyzer-optin.performance.Padding)
|
||||||
|
|
||||||
static int convert_errno_from_zlib(int zr) {
|
static int convert_errno_from_zlib(int zr) {
|
||||||
switch (zr) {
|
switch (zr) {
|
||||||
case Z_OK:
|
case Z_OK:
|
||||||
@@ -307,4 +309,6 @@ TEST_CASE("upx_zlib_decompress") {
|
|||||||
UNUSED(r);
|
UNUSED(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // WITH_ZLIB
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+8
-33
@@ -397,39 +397,6 @@ inline void NO_fprintf(FILE *, const char *, ...) noexcept {}
|
|||||||
|
|
||||||
#define TABLESIZE(table) ((sizeof(table) / sizeof((table)[0])))
|
#define TABLESIZE(table) ((sizeof(table) / sizeof((table)[0])))
|
||||||
|
|
||||||
// TODO later: move these to upx namespace in util/cxxlib.h; also see bele.h
|
|
||||||
template <class T>
|
|
||||||
inline T ALIGN_DOWN(const T &a, const T &b) {
|
|
||||||
T r;
|
|
||||||
r = (a / b) * b;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
template <class T>
|
|
||||||
inline T ALIGN_UP(const T &a, const T &b) {
|
|
||||||
T r;
|
|
||||||
r = ((a + b - 1) / b) * b;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
template <class T>
|
|
||||||
inline T ALIGN_GAP(const T &a, const T &b) {
|
|
||||||
T r;
|
|
||||||
r = ALIGN_UP(a, b) - a;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
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 <class T>
|
template <class T>
|
||||||
inline void mem_clear(T *object) noexcept {
|
inline void mem_clear(T *object) noexcept {
|
||||||
static_assert(std::is_class_v<T>); // UPX convention
|
static_assert(std::is_class_v<T>); // UPX convention
|
||||||
@@ -483,6 +450,12 @@ using upx::OptVar;
|
|||||||
using upx::tribool;
|
using upx::tribool;
|
||||||
#define usizeof(expr) (upx::UnsignedSizeOf<sizeof(expr)>::value)
|
#define usizeof(expr) (upx::UnsignedSizeOf<sizeof(expr)>::value)
|
||||||
|
|
||||||
|
#define ALIGN_DOWN(a, b) upx::align_down((a), (b))
|
||||||
|
#define ALIGN_UP(a, b) upx::align_up((a), (b))
|
||||||
|
#define ALIGN_GAP(a, b) upx::align_gap((a), (b))
|
||||||
|
#define UPX_MAX(a, b) upx::max((a), (b))
|
||||||
|
#define UPX_MIN(a, b) upx::min((a), (b))
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// constants
|
// constants
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -623,7 +596,9 @@ using upx::tribool;
|
|||||||
|
|
||||||
#define WITH_LZMA 1
|
#define WITH_LZMA 1
|
||||||
#define WITH_UCL 1
|
#define WITH_UCL 1
|
||||||
|
#ifndef WITH_ZLIB
|
||||||
#define WITH_ZLIB 1
|
#define WITH_ZLIB 1
|
||||||
|
#endif
|
||||||
#if (WITH_UCL)
|
#if (WITH_UCL)
|
||||||
#define ucl_compress_config_t REAL_ucl_compress_config_t
|
#define ucl_compress_config_t REAL_ucl_compress_config_t
|
||||||
#include <ucl/include/ucl/uclconf.h>
|
#include <ucl/include/ucl/uclconf.h>
|
||||||
|
|||||||
@@ -1246,7 +1246,9 @@ int upx_main(int argc, char *argv[]) may_throw {
|
|||||||
assert(upx_nrv_init() == 0);
|
assert(upx_nrv_init() == 0);
|
||||||
#endif
|
#endif
|
||||||
assert(upx_ucl_init() == 0);
|
assert(upx_ucl_init() == 0);
|
||||||
|
#if (WITH_ZLIB)
|
||||||
assert(upx_zlib_init() == 0);
|
assert(upx_zlib_init() == 0);
|
||||||
|
#endif
|
||||||
#if (WITH_ZSTD)
|
#if (WITH_ZSTD)
|
||||||
assert(upx_zstd_init() == 0);
|
assert(upx_zstd_init() == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+30
-40
@@ -43,6 +43,8 @@
|
|||||||
#include "p_lx_elf.h"
|
#include "p_lx_elf.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
|
||||||
|
using upx::umax, upx::umin;
|
||||||
|
|
||||||
#define PT_LOAD32 Elf32_Phdr::PT_LOAD
|
#define PT_LOAD32 Elf32_Phdr::PT_LOAD
|
||||||
#define PT_LOAD64 Elf64_Phdr::PT_LOAD
|
#define PT_LOAD64 Elf64_Phdr::PT_LOAD
|
||||||
#define PT_NOTE32 Elf32_Phdr::PT_NOTE
|
#define PT_NOTE32 Elf32_Phdr::PT_NOTE
|
||||||
@@ -66,18 +68,6 @@ static unsigned const EF_ARM_EABI_VER5 = 0x05000000;
|
|||||||
/*offset 20*/ '.','s','h','s','t','r','t','a','b','\0'
|
/*offset 20*/ '.','s','h','s','t','r','t','a','b','\0'
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned
|
|
||||||
umin(unsigned a, unsigned b)
|
|
||||||
{
|
|
||||||
return (a < b) ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static upx_uint64_t
|
|
||||||
umin64(upx_uint64_t a, upx_uint64_t b)
|
|
||||||
{
|
|
||||||
return (a < b) ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
up4(unsigned x)
|
up4(unsigned x)
|
||||||
{
|
{
|
||||||
@@ -357,7 +347,7 @@ PackLinuxElf32::PackLinuxElf32help1(InputFile *f)
|
|||||||
unsigned offset = check_pt_dynamic(phdr);
|
unsigned offset = check_pt_dynamic(phdr);
|
||||||
dynseg= (Elf32_Dyn *)(offset + file_image);
|
dynseg= (Elf32_Dyn *)(offset + file_image);
|
||||||
invert_pt_dynamic(dynseg,
|
invert_pt_dynamic(dynseg,
|
||||||
umin(get_te32(&phdr->p_filesz), file_size - offset));
|
umin(get_te32(&phdr->p_filesz), (unsigned)(file_size_u - offset)));
|
||||||
}
|
}
|
||||||
else if (is_LOAD32(phdr)) {
|
else if (is_LOAD32(phdr)) {
|
||||||
check_pt_load(phdr);
|
check_pt_load(phdr);
|
||||||
@@ -1069,7 +1059,7 @@ PackLinuxElf64::PackLinuxElf64help1(InputFile *f)
|
|||||||
upx_uint64_t offset = check_pt_dynamic(phdr);
|
upx_uint64_t offset = check_pt_dynamic(phdr);
|
||||||
dynseg= (Elf64_Dyn *)(offset + file_image);
|
dynseg= (Elf64_Dyn *)(offset + file_image);
|
||||||
invert_pt_dynamic(dynseg,
|
invert_pt_dynamic(dynseg,
|
||||||
umin(get_te64(&phdr->p_filesz), file_size - offset));
|
umin(get_te64(&phdr->p_filesz), file_size_u - offset));
|
||||||
}
|
}
|
||||||
else if (PT_LOAD64==get_te32(&phdr->p_type)) {
|
else if (PT_LOAD64==get_te32(&phdr->p_type)) {
|
||||||
check_pt_load(phdr);
|
check_pt_load(phdr);
|
||||||
@@ -2699,7 +2689,7 @@ tribool PackLinuxElf32::canPack()
|
|||||||
unsigned offset = check_pt_dynamic(phdr);
|
unsigned offset = check_pt_dynamic(phdr);
|
||||||
dynseg= (Elf32_Dyn *)(offset + file_image);
|
dynseg= (Elf32_Dyn *)(offset + file_image);
|
||||||
invert_pt_dynamic(dynseg,
|
invert_pt_dynamic(dynseg,
|
||||||
umin(get_te32(&phdr->p_filesz), file_size - offset));
|
umin(get_te32(&phdr->p_filesz), (unsigned)(file_size_u - offset)));
|
||||||
}
|
}
|
||||||
else if (is_LOAD32(phdr)) {
|
else if (is_LOAD32(phdr)) {
|
||||||
if (!pload_x0
|
if (!pload_x0
|
||||||
@@ -2773,7 +2763,7 @@ tribool PackLinuxElf32::canPack()
|
|||||||
for (int j= e_shnum; --j>=0; ++shdr) {
|
for (int j= e_shnum; --j>=0; ++shdr) {
|
||||||
unsigned const sh_type = get_te32(&shdr->sh_type);
|
unsigned const sh_type = get_te32(&shdr->sh_type);
|
||||||
if (Elf32_Shdr::SHF_EXECINSTR & get_te32(&shdr->sh_flags)) {
|
if (Elf32_Shdr::SHF_EXECINSTR & get_te32(&shdr->sh_flags)) {
|
||||||
xct_va = umin(xct_va, get_te32(&shdr->sh_addr));
|
xct_va = umin((unsigned) xct_va, get_te32(&shdr->sh_addr));
|
||||||
}
|
}
|
||||||
// Hook the first slot of DT_PREINIT_ARRAY or DT_INIT_ARRAY.
|
// Hook the first slot of DT_PREINIT_ARRAY or DT_INIT_ARRAY.
|
||||||
if (!user_init_rp && (
|
if (!user_init_rp && (
|
||||||
@@ -3797,7 +3787,7 @@ PackLinuxElf64::generateElfHdr(
|
|||||||
for (int j= e_phnum; --j>=0; ) {
|
for (int j= e_phnum; --j>=0; ) {
|
||||||
if (PT_LOAD64 == get_te32(&phdri[j].p_type)) {
|
if (PT_LOAD64 == get_te32(&phdri[j].p_type)) {
|
||||||
upx_uint64_t const vaddr = get_te64(&phdri[j].p_vaddr);
|
upx_uint64_t const vaddr = get_te64(&phdri[j].p_vaddr);
|
||||||
lo_va_user = umin64(lo_va_user, vaddr);
|
lo_va_user = umin(lo_va_user, vaddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_te64( &h2->phdr[C_BASE].p_vaddr, lo_va_user);
|
set_te64( &h2->phdr[C_BASE].p_vaddr, lo_va_user);
|
||||||
@@ -5108,7 +5098,7 @@ int PackLinuxElf32::pack2(OutputFile *fo, Filter &ft)
|
|||||||
asl_pack2_Shdrs(fo, pre_xct_top);
|
asl_pack2_Shdrs(fo, pre_xct_top);
|
||||||
}
|
}
|
||||||
else { // Just copy up to xct_off
|
else { // Just copy up to xct_off
|
||||||
x.size = umin(x.size, xct_off - x.offset);
|
x.size = umin(0ull + x.size, 0ull + xct_off - x.offset);
|
||||||
if (0) { // DEBUG paranoia
|
if (0) { // DEBUG paranoia
|
||||||
fi->seek(x.offset, SEEK_SET);
|
fi->seek(x.offset, SEEK_SET);
|
||||||
fi->readx(ibuf, x.size);
|
fi->readx(ibuf, x.size);
|
||||||
@@ -5366,7 +5356,7 @@ int PackLinuxElf64::pack2(OutputFile *fo, Filter &ft)
|
|||||||
asl_pack2_Shdrs(fo, pre_xct_top);
|
asl_pack2_Shdrs(fo, pre_xct_top);
|
||||||
}
|
}
|
||||||
else { // Just copy up to xct_off
|
else { // Just copy up to xct_off
|
||||||
x.size = umin(x.size, xct_off - x.offset);
|
x.size = umin(0ull + x.size, 0ull + xct_off - x.offset);
|
||||||
if (0) { // DEBUG paranoia
|
if (0) { // DEBUG paranoia
|
||||||
fi->seek(x.offset, SEEK_SET);
|
fi->seek(x.offset, SEEK_SET);
|
||||||
fi->readx(ibuf, x.size);
|
fi->readx(ibuf, x.size);
|
||||||
@@ -6444,7 +6434,7 @@ void PackLinuxElf64::un_shlib_1(
|
|||||||
|
|
||||||
// Below xct_off is not compressed (for benefit of rtld.)
|
// Below xct_off is not compressed (for benefit of rtld.)
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
fi->readx(ibuf, umin(blocksize, file_size));
|
fi->readx(ibuf, umin(blocksize, file_size_u32));
|
||||||
|
|
||||||
// Determine if the extra page with copy of _Shdrs was spliced in.
|
// Determine if the extra page with copy of _Shdrs was spliced in.
|
||||||
// This used to be the result of --android-shlib.
|
// This used to be the result of --android-shlib.
|
||||||
@@ -6457,7 +6447,7 @@ void PackLinuxElf64::un_shlib_1(
|
|||||||
if (e_shoff && e_shnum
|
if (e_shoff && e_shnum
|
||||||
// +36: (sizeof(PackHeader) + sizeof(overlay_offset))
|
// +36: (sizeof(PackHeader) + sizeof(overlay_offset))
|
||||||
// after Shdrs for ARM_ATTRIBUTES
|
// after Shdrs for ARM_ATTRIBUTES
|
||||||
&& (((e_shoff + sizeof(Elf64_Shdr) * e_shnum) + 36) < (upx_uint64_t)file_size)
|
&& (((e_shoff + sizeof(Elf64_Shdr) * e_shnum) + 36) < file_size_u)
|
||||||
) { // possible --android-shlib
|
) { // possible --android-shlib
|
||||||
unsigned x = get_te32(&file_image[get_te64(&ehdri.e_entry) - (1+ 4)*sizeof(int)]);
|
unsigned x = get_te32(&file_image[get_te64(&ehdri.e_entry) - (1+ 4)*sizeof(int)]);
|
||||||
if (1 & x) { // the clincher
|
if (1 & x) { // the clincher
|
||||||
@@ -6644,7 +6634,7 @@ void PackLinuxElf32::un_shlib_1(
|
|||||||
|
|
||||||
// Below xct_off is not compressed (for benefit of rtld.)
|
// Below xct_off is not compressed (for benefit of rtld.)
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
fi->readx(ibuf, umin(blocksize, file_size));
|
fi->readx(ibuf, umin(blocksize, file_size_u32));
|
||||||
|
|
||||||
// Determine if the extra page with copy of _Shdrs was spliced in.
|
// Determine if the extra page with copy of _Shdrs was spliced in.
|
||||||
// This used to be the result of --android-shlib.
|
// This used to be the result of --android-shlib.
|
||||||
@@ -6657,7 +6647,7 @@ void PackLinuxElf32::un_shlib_1(
|
|||||||
if (e_shoff && e_shnum
|
if (e_shoff && e_shnum
|
||||||
// +36: (sizeof(PackHeader) + sizeof(overlay_offset))
|
// +36: (sizeof(PackHeader) + sizeof(overlay_offset))
|
||||||
// after Shdrs for ARM_ATTRIBUTES
|
// after Shdrs for ARM_ATTRIBUTES
|
||||||
&& (((e_shoff + sizeof(Elf32_Shdr) * e_shnum) + 36) < (upx_uint32_t)file_size)
|
&& (((e_shoff + sizeof(Elf32_Shdr) * e_shnum) + 36) < file_size_u32)
|
||||||
) { // possible --android-shlib
|
) { // possible --android-shlib
|
||||||
unsigned x = get_te32(&file_image[get_te32(&ehdri.e_entry) - (1+ 4)*sizeof(int)]);
|
unsigned x = get_te32(&file_image[get_te32(&ehdri.e_entry) - (1+ 4)*sizeof(int)]);
|
||||||
if (1 & x) { // the clincher
|
if (1 & x) { // the clincher
|
||||||
@@ -6844,7 +6834,7 @@ void PackLinuxElf32::un_DT_INIT(
|
|||||||
upx_uint32_t dt_relsz(0), dt_rel(0);
|
upx_uint32_t dt_relsz(0), dt_rel(0);
|
||||||
upx_uint32_t const dyn_len = get_te32(&dynhdr->p_filesz);
|
upx_uint32_t const dyn_len = get_te32(&dynhdr->p_filesz);
|
||||||
upx_uint32_t const dyn_off = get_te32(&dynhdr->p_offset);
|
upx_uint32_t const dyn_off = get_te32(&dynhdr->p_offset);
|
||||||
if ((unsigned long)file_size < (dyn_len + dyn_off)) {
|
if (file_size_u32 < (dyn_len + dyn_off)) {
|
||||||
char msg[50]; snprintf(msg, sizeof(msg),
|
char msg[50]; snprintf(msg, sizeof(msg),
|
||||||
"bad PT_DYNAMIC .p_filesz %#lx", (long unsigned)dyn_len);
|
"bad PT_DYNAMIC .p_filesz %#lx", (long unsigned)dyn_len);
|
||||||
throwCantUnpack(msg);
|
throwCantUnpack(msg);
|
||||||
@@ -6853,7 +6843,7 @@ void PackLinuxElf32::un_DT_INIT(
|
|||||||
fi->readx(ibuf, dyn_len);
|
fi->readx(ibuf, dyn_len);
|
||||||
Elf32_Dyn *dyn = (Elf32_Dyn *)(void *)ibuf;
|
Elf32_Dyn *dyn = (Elf32_Dyn *)(void *)ibuf;
|
||||||
dynseg = dyn; invert_pt_dynamic(dynseg,
|
dynseg = dyn; invert_pt_dynamic(dynseg,
|
||||||
umin(dyn_len, file_size - dyn_off));
|
umin(dyn_len, file_size_u32 - dyn_off));
|
||||||
for (unsigned j2= 0; j2 < dyn_len; ++dyn, j2 += sizeof(*dyn)) {
|
for (unsigned j2= 0; j2 < dyn_len; ++dyn, j2 += sizeof(*dyn)) {
|
||||||
upx_uint32_t const tag = get_te32(&dyn->d_tag);
|
upx_uint32_t const tag = get_te32(&dyn->d_tag);
|
||||||
upx_uint32_t val = get_te32(&dyn->d_val);
|
upx_uint32_t val = get_te32(&dyn->d_val);
|
||||||
@@ -7023,7 +7013,7 @@ void PackLinuxElf64::un_DT_INIT(
|
|||||||
upx_uint64_t dt_relasz(0), dt_rela(0);
|
upx_uint64_t dt_relasz(0), dt_rela(0);
|
||||||
upx_uint64_t const dyn_len = get_te64(&dynhdr->p_filesz);
|
upx_uint64_t const dyn_len = get_te64(&dynhdr->p_filesz);
|
||||||
upx_uint64_t const dyn_off = get_te64(&dynhdr->p_offset);
|
upx_uint64_t const dyn_off = get_te64(&dynhdr->p_offset);
|
||||||
if ((unsigned long)file_size < (dyn_len + dyn_off)) {
|
if (file_size_u < (dyn_len + dyn_off)) {
|
||||||
char msg[50]; snprintf(msg, sizeof(msg),
|
char msg[50]; snprintf(msg, sizeof(msg),
|
||||||
"bad PT_DYNAMIC .p_filesz %#lx", (long unsigned)dyn_len);
|
"bad PT_DYNAMIC .p_filesz %#lx", (long unsigned)dyn_len);
|
||||||
throwCantUnpack(msg);
|
throwCantUnpack(msg);
|
||||||
@@ -7032,7 +7022,7 @@ void PackLinuxElf64::un_DT_INIT(
|
|||||||
fi->readx(ibuf, dyn_len);
|
fi->readx(ibuf, dyn_len);
|
||||||
Elf64_Dyn *dyn = (Elf64_Dyn *)(void *)ibuf;
|
Elf64_Dyn *dyn = (Elf64_Dyn *)(void *)ibuf;
|
||||||
dynseg = dyn; invert_pt_dynamic(dynseg,
|
dynseg = dyn; invert_pt_dynamic(dynseg,
|
||||||
umin(dyn_len, file_size - dyn_off));
|
umin(dyn_len, file_size_u - dyn_off));
|
||||||
for (unsigned j2= 0; j2 < dyn_len; ++dyn, j2 += sizeof(*dyn)) {
|
for (unsigned j2= 0; j2 < dyn_len; ++dyn, j2 += sizeof(*dyn)) {
|
||||||
upx_uint64_t const tag = get_te64(&dyn->d_tag);
|
upx_uint64_t const tag = get_te64(&dyn->d_tag);
|
||||||
upx_uint64_t val = get_te64(&dyn->d_val);
|
upx_uint64_t val = get_te64(&dyn->d_val);
|
||||||
@@ -7238,7 +7228,7 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
|||||||
fi->readx(&bhdr, szb_info);
|
fi->readx(&bhdr, szb_info);
|
||||||
ph.u_len = get_te32(&bhdr.sz_unc);
|
ph.u_len = get_te32(&bhdr.sz_unc);
|
||||||
ph.c_len = get_te32(&bhdr.sz_cpr);
|
ph.c_len = get_te32(&bhdr.sz_cpr);
|
||||||
if (ph.c_len > (unsigned)file_size || ph.c_len == 0 || ph.u_len == 0
|
if (ph.c_len > file_size_u || ph.c_len == 0 || ph.u_len == 0
|
||||||
|| ph.u_len > orig_file_size)
|
|| ph.u_len > orig_file_size)
|
||||||
throwCantUnpack("b_info corrupted");
|
throwCantUnpack("b_info corrupted");
|
||||||
ph.filter_cto = bhdr.b_cto8;
|
ph.filter_cto = bhdr.b_cto8;
|
||||||
@@ -7306,7 +7296,7 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
|||||||
fi->seek(- (off_t) (szb_info + ph.c_len), SEEK_CUR);
|
fi->seek(- (off_t) (szb_info + ph.c_len), SEEK_CUR);
|
||||||
|
|
||||||
u_phnum = get_te16(&ehdr->e_phnum);
|
u_phnum = get_te16(&ehdr->e_phnum);
|
||||||
if ((umin64(MAX_ELF_HDR_64, ph.u_len) - sizeof(Elf64_Ehdr))/sizeof(Elf64_Phdr) < u_phnum) {
|
if ((umin(MAX_ELF_HDR_64, ph.u_len) - sizeof(Elf64_Ehdr))/sizeof(Elf64_Phdr) < u_phnum) {
|
||||||
throwCantUnpack("bad compressed e_phnum");
|
throwCantUnpack("bad compressed e_phnum");
|
||||||
}
|
}
|
||||||
o_elfhdrs.alloc(sizeof(Elf64_Ehdr) + u_phnum * sizeof(Elf64_Phdr));
|
o_elfhdrs.alloc(sizeof(Elf64_Ehdr) + u_phnum * sizeof(Elf64_Phdr));
|
||||||
@@ -7681,7 +7671,7 @@ PackLinuxElf32::elf_get_offset_from_Phdrs(unsigned addr, Elf32_Phdr const *phdr0
|
|||||||
unsigned const t = addr - get_te32(&phdr->p_vaddr);
|
unsigned const t = addr - get_te32(&phdr->p_vaddr);
|
||||||
if (t < get_te32(&phdr->p_filesz)) {
|
if (t < get_te32(&phdr->p_filesz)) {
|
||||||
unsigned const p_offset = get_te32(&phdr->p_offset);
|
unsigned const p_offset = get_te32(&phdr->p_offset);
|
||||||
if ((u32_t)file_size <= p_offset) { // FIXME: weak
|
if (file_size_u <= p_offset) { // FIXME: weak
|
||||||
char msg[40]; snprintf(msg, sizeof(msg),
|
char msg[40]; snprintf(msg, sizeof(msg),
|
||||||
"bad Elf32_Phdr[%d].p_offset %x",
|
"bad Elf32_Phdr[%d].p_offset %x",
|
||||||
-1+ e_phnum - j, p_offset);
|
-1+ e_phnum - j, p_offset);
|
||||||
@@ -7703,9 +7693,9 @@ PackLinuxElf32::check_pt_load(Elf32_Phdr const *const phdr)
|
|||||||
u32_t align = get_te32(&phdr->p_align);
|
u32_t align = get_te32(&phdr->p_align);
|
||||||
|
|
||||||
if ((-1+ align) & (paddr ^ vaddr)
|
if ((-1+ align) & (paddr ^ vaddr)
|
||||||
|| (u32_t)file_size <= (u32_t)offset
|
|| file_size_u32 <= (u32_t)offset
|
||||||
|| (u32_t)file_size < (u32_t)offend
|
|| file_size_u32 < (u32_t)offend
|
||||||
|| (u32_t)file_size < (u32_t)filesz) {
|
|| file_size_u32 < (u32_t)filesz) {
|
||||||
char msg[50]; snprintf(msg, sizeof(msg), "bad PT_LOAD phdr[%u]",
|
char msg[50]; snprintf(msg, sizeof(msg), "bad PT_LOAD phdr[%u]",
|
||||||
(unsigned)(phdr - phdri));
|
(unsigned)(phdr - phdri));
|
||||||
throwCantPack(msg);
|
throwCantPack(msg);
|
||||||
@@ -7789,7 +7779,7 @@ PackLinuxElf32::elf_find_dynamic(unsigned int key) const
|
|||||||
Elf32_Dyn const *dynp= elf_find_dynptr(key);
|
Elf32_Dyn const *dynp= elf_find_dynptr(key);
|
||||||
if (dynp) {
|
if (dynp) {
|
||||||
unsigned const t= elf_get_offset_from_address(get_te32(&dynp->d_val));
|
unsigned const t= elf_get_offset_from_address(get_te32(&dynp->d_val));
|
||||||
if (t && t < (unsigned)file_size) {
|
if (t && t < file_size_u) {
|
||||||
return t + file_image;
|
return t + file_image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7802,7 +7792,7 @@ PackLinuxElf64::elf_find_dynamic(unsigned int key) const
|
|||||||
Elf64_Dyn const *dynp= elf_find_dynptr(key);
|
Elf64_Dyn const *dynp= elf_find_dynptr(key);
|
||||||
if (dynp) {
|
if (dynp) {
|
||||||
upx_uint64_t const t= elf_get_offset_from_address(get_te64(&dynp->d_val));
|
upx_uint64_t const t= elf_get_offset_from_address(get_te64(&dynp->d_val));
|
||||||
if (t && t < (upx_uint64_t)file_size) {
|
if (t && t < file_size_u) {
|
||||||
return t + file_image;
|
return t + file_image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7838,7 +7828,7 @@ PackLinuxElf64::elf_get_offset_from_address(upx_uint64_t addr) const
|
|||||||
upx_uint64_t const t = addr - get_te64(&phdr->p_vaddr);
|
upx_uint64_t const t = addr - get_te64(&phdr->p_vaddr);
|
||||||
if (t < get_te64(&phdr->p_filesz)) {
|
if (t < get_te64(&phdr->p_filesz)) {
|
||||||
upx_uint64_t const p_offset = get_te64(&phdr->p_offset);
|
upx_uint64_t const p_offset = get_te64(&phdr->p_offset);
|
||||||
if ((u64_t)file_size <= p_offset) { // FIXME: weak
|
if (file_size_u <= p_offset) { // FIXME: weak
|
||||||
char msg[40]; snprintf(msg, sizeof(msg),
|
char msg[40]; snprintf(msg, sizeof(msg),
|
||||||
"bad Elf64_Phdr[%d].p_offset %#lx",
|
"bad Elf64_Phdr[%d].p_offset %#lx",
|
||||||
-1+ e_phnum - j, (long unsigned)p_offset);
|
-1+ e_phnum - j, (long unsigned)p_offset);
|
||||||
@@ -7860,9 +7850,9 @@ PackLinuxElf64::check_pt_load(Elf64_Phdr const *const phdr)
|
|||||||
u64_t align = get_te64(&phdr->p_align);
|
u64_t align = get_te64(&phdr->p_align);
|
||||||
|
|
||||||
if ((-1+ align) & (paddr ^ vaddr)
|
if ((-1+ align) & (paddr ^ vaddr)
|
||||||
|| (u64_t)file_size <= (u64_t)offset
|
|| file_size_u <= (u64_t)offset
|
||||||
|| (u64_t)file_size < (u64_t)offend
|
|| file_size_u < (u64_t)offend
|
||||||
|| (u64_t)file_size < (u64_t)filesz) {
|
|| file_size_u < (u64_t)filesz) {
|
||||||
char msg[50]; snprintf(msg, sizeof(msg), "bad PT_LOAD phdr[%u]",
|
char msg[50]; snprintf(msg, sizeof(msg), "bad PT_LOAD phdr[%u]",
|
||||||
(unsigned)(phdr - phdri));
|
(unsigned)(phdr - phdri));
|
||||||
throwCantPack(msg);
|
throwCantPack(msg);
|
||||||
@@ -8072,7 +8062,7 @@ PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp, upx_uint64_t headway)
|
|||||||
|
|
||||||
unsigned const v_sym = !x_sym ? 0 : get_te64(&dynp0[-1+ x_sym].d_val); // UPX_RSIZE_MAX_MEM
|
unsigned const v_sym = !x_sym ? 0 : get_te64(&dynp0[-1+ x_sym].d_val); // UPX_RSIZE_MAX_MEM
|
||||||
if ((unsigned)(hashend - buckets) < nbucket
|
if ((unsigned)(hashend - buckets) < nbucket
|
||||||
|| !v_sym || (unsigned)file_size <= v_sym
|
|| !v_sym || file_size_u <= v_sym
|
||||||
|| ((v_hsh < v_sym) && (v_sym - v_hsh) < sizeof(*buckets)*(2+ nbucket))
|
|| ((v_hsh < v_sym) && (v_sym - v_hsh) < sizeof(*buckets)*(2+ nbucket))
|
||||||
) {
|
) {
|
||||||
char msg[80]; snprintf(msg, sizeof(msg),
|
char msg[80]; snprintf(msg, sizeof(msg),
|
||||||
|
|||||||
+1
-10
@@ -279,15 +279,6 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
|||||||
fo->rewrite(&elfout, overlay_offset);
|
fo->rewrite(&elfout, overlay_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned
|
|
||||||
umax(unsigned a, unsigned b)
|
|
||||||
{
|
|
||||||
if (a <= b) {
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
Linker *PackLinuxI386::newLinker() const
|
Linker *PackLinuxI386::newLinker() const
|
||||||
{
|
{
|
||||||
return new ElfLinkerX86;
|
return new ElfLinkerX86;
|
||||||
@@ -311,7 +302,7 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
usizeof(l_info);
|
usizeof(l_info);
|
||||||
if (0 == get_le32(fold_hdrlen + fold)) {
|
if (0 == get_le32(fold_hdrlen + fold)) {
|
||||||
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
||||||
fold_hdrlen = umax(0x80, fold_hdrlen);
|
fold_hdrlen = upx::umax(0x80u, fold_hdrlen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// This adds the definition to the "library", to be used later.
|
// This adds the definition to the "library", to be used later.
|
||||||
|
|||||||
+1
-10
@@ -62,15 +62,6 @@ PackLinuxI386sh::~PackLinuxI386sh()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned
|
|
||||||
umax(unsigned a, unsigned b)
|
|
||||||
{
|
|
||||||
if (a <= b) {
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PackLinuxI386sh::buildLoader(Filter const *ft)
|
PackLinuxI386sh::buildLoader(Filter const *ft)
|
||||||
{
|
{
|
||||||
@@ -94,7 +85,7 @@ PackLinuxI386sh::buildLoader(Filter const *ft)
|
|||||||
sizeof(Elf32_Phdr) * get_te16(&((Elf32_Ehdr const *)(void *)buf)->e_phnum);
|
sizeof(Elf32_Phdr) * get_te16(&((Elf32_Ehdr const *)(void *)buf)->e_phnum);
|
||||||
if (0 == get_le32(buf + fold_hdrlen)) {
|
if (0 == get_le32(buf + fold_hdrlen)) {
|
||||||
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
||||||
fold_hdrlen = umax(0x80, fold_hdrlen);
|
fold_hdrlen = upx::umax(0x80u, fold_hdrlen);
|
||||||
}
|
}
|
||||||
bool success = fold_ft.filter(buf + fold_hdrlen, sz_fold - fold_hdrlen);
|
bool success = fold_ft.filter(buf + fold_hdrlen, sz_fold - fold_hdrlen);
|
||||||
UNUSED(success);
|
UNUSED(success);
|
||||||
|
|||||||
+3
-9
@@ -1462,12 +1462,6 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
|
|||||||
#define WANT_MACH_HEADER_ENUM 1
|
#define WANT_MACH_HEADER_ENUM 1
|
||||||
#include "p_mach_enum.h"
|
#include "p_mach_enum.h"
|
||||||
|
|
||||||
static unsigned
|
|
||||||
umin(unsigned a, unsigned b)
|
|
||||||
{
|
|
||||||
return (a <= b) ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAX_N_CMDS 256
|
#define MAX_N_CMDS 256
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@@ -1549,7 +1543,7 @@ void PackMachBase<T>::unpack(OutputFile *fo)
|
|||||||
"bad packed Mach load_command @%#x", ptr_udiff_bytes(ptr, mhdr));
|
"bad packed Mach load_command @%#x", ptr_udiff_bytes(ptr, mhdr));
|
||||||
throwCantUnpack(msg);
|
throwCantUnpack(msg);
|
||||||
}
|
}
|
||||||
memcpy(&msegcmd[j], ptr, umin(sizeof(Mach_segment_command), cmdsize));
|
memcpy(&msegcmd[j], ptr, upx::umin(usizeof(Mach_segment_command), cmdsize));
|
||||||
headway -= cmdsize;
|
headway -= cmdsize;
|
||||||
ptr += cmdsize;
|
ptr += cmdsize;
|
||||||
}
|
}
|
||||||
@@ -1903,7 +1897,7 @@ tribool PackMachBase<T>::canUnpack()
|
|||||||
if ( overlay_offset < sz_mach_headers
|
if ( overlay_offset < sz_mach_headers
|
||||||
|| (off_t)overlay_offset >= file_size) {
|
|| (off_t)overlay_offset >= file_size) {
|
||||||
infoWarning("file corrupted: %s", fi->getName());
|
infoWarning("file corrupted: %s", fi->getName());
|
||||||
MemBuffer buf2(umin(1<<14, file_size));
|
MemBuffer buf2(upx::umin(1u<<14, file_size_u32));
|
||||||
fi->seek(sz_mach_headers, SEEK_SET);
|
fi->seek(sz_mach_headers, SEEK_SET);
|
||||||
fi->readx(buf2, buf2.getSize());
|
fi->readx(buf2, buf2.getSize());
|
||||||
unsigned const *p = (unsigned const *)&buf2[0];
|
unsigned const *p = (unsigned const *)&buf2[0];
|
||||||
@@ -1966,7 +1960,7 @@ tribool PackMachBase<T>::canPack()
|
|||||||
throwCantPack("%d < Mach_header.ncmds", MAX_N_CMDS);
|
throwCantPack("%d < Mach_header.ncmds", MAX_N_CMDS);
|
||||||
}
|
}
|
||||||
unsigned const sz_mhcmds = (unsigned)mhdri.sizeofcmds;
|
unsigned const sz_mhcmds = (unsigned)mhdri.sizeofcmds;
|
||||||
unsigned headway = umin(sz_mhcmds, file_size - sizeof(mhdri));
|
unsigned headway = upx::umin(sz_mhcmds, file_size_u32 - usizeof(mhdri));
|
||||||
if (headway < sz_mhcmds) {
|
if (headway < sz_mhcmds) {
|
||||||
char buf[32]; snprintf(buf, sizeof(buf), "bad sizeofcmds %d", sz_mhcmds);
|
char buf[32]; snprintf(buf, sizeof(buf), "bad sizeofcmds %d", sz_mhcmds);
|
||||||
throwCantPack(buf);
|
throwCantPack(buf);
|
||||||
|
|||||||
+1
-3
@@ -599,8 +599,6 @@ int PackUnix::find_overlay_offset(MemBuffer const &buf)
|
|||||||
// See notes there.
|
// See notes there.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static unsigned umax(unsigned a, unsigned b) {return (a < b) ? b : a;}
|
|
||||||
|
|
||||||
void PackUnix::unpack(OutputFile *fo)
|
void PackUnix::unpack(OutputFile *fo)
|
||||||
{
|
{
|
||||||
b_info bhdr;
|
b_info bhdr;
|
||||||
@@ -671,7 +669,7 @@ void PackUnix::unpack(OutputFile *fo)
|
|||||||
// first flag bits of NRV_d32, the 5-byte info of LZMA, etc.
|
// first flag bits of NRV_d32, the 5-byte info of LZMA, etc.
|
||||||
// Fuzzers may try sz_cpr shorter than possible.
|
// Fuzzers may try sz_cpr shorter than possible.
|
||||||
// Use some OVERHEAD for safety.
|
// Use some OVERHEAD for safety.
|
||||||
i = blocksize + OVERHEAD - umax(12, sz_cpr);
|
i = blocksize + OVERHEAD - upx::umax(12u, sz_cpr);
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
throwCantUnpack("corrupt b_info");
|
throwCantUnpack("corrupt b_info");
|
||||||
fi->readx(buf+i, sz_cpr);
|
fi->readx(buf+i, sz_cpr);
|
||||||
|
|||||||
+2
-2
@@ -76,8 +76,8 @@ protected:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct Extent {
|
struct Extent {
|
||||||
off_t offset;
|
upx_off_t offset;
|
||||||
off_t size;
|
upx_off_t size;
|
||||||
};
|
};
|
||||||
virtual void packExtent(const Extent &x,
|
virtual void packExtent(const Extent &x,
|
||||||
Filter *, OutputFile *,
|
Filter *, OutputFile *,
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#define ALLOW_INT_PLUS_MEMBUFFER 1
|
#define ALLOW_INT_PLUS_MEMBUFFER 1
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
|
||||||
|
#if (WITH_ZLIB)
|
||||||
#include "p_elf.h"
|
#include "p_elf.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
@@ -1071,4 +1072,6 @@ void PackVmlinuzARMEL::unpack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // WITH_ZLIB
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+5
-2
@@ -36,9 +36,12 @@
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
PackerBase::PackerBase(InputFile *f) : fi(f), file_size(f ? f->st_size() : 0) {
|
PackerBase::PackerBase(InputFile *f)
|
||||||
|
: fi(f), file_size(f != nullptr ? f->st_size() : 0), file_size_i32(file_size) {
|
||||||
ph.reset();
|
ph.reset();
|
||||||
mem_size_assert(1, file_size);
|
mem_size_assert(1, file_size_u);
|
||||||
|
assert_noexcept(file_size_i32 == file_size);
|
||||||
|
assert_noexcept(file_size_u32 == file_size_u);
|
||||||
}
|
}
|
||||||
|
|
||||||
Packer::Packer(InputFile *f) : PackerBase(f) { uip = new UiPacker(this); }
|
Packer::Packer(InputFile *f) : PackerBase(f) { uip = new UiPacker(this); }
|
||||||
|
|||||||
+11
-4
@@ -81,10 +81,17 @@ public:
|
|||||||
static constexpr unsigned MAX_FILTERS = 16; // for getFilters()
|
static constexpr unsigned MAX_FILTERS = 16; // for getFilters()
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
InputFile *const fi; // reference
|
InputFile *const fi; // reference
|
||||||
union { // unnamed union
|
// multiple names for "file_size" to avoid casts
|
||||||
const upx_int64_t file_size; // must get set by constructor
|
union { // unnamed union
|
||||||
const upx_uint64_t file_size_u; // (explicitly unsigned to avoid -Wsign-compare casts)
|
const upx_int64_t file_size; // must get set by constructor
|
||||||
|
const upx_uint64_t file_size_u;
|
||||||
|
const upx_int64_t file_size_i64;
|
||||||
|
const upx_uint64_t file_size_u64;
|
||||||
|
};
|
||||||
|
union { // unnamed union
|
||||||
|
const upx_int32_t file_size_i32;
|
||||||
|
const upx_uint32_t file_size_u32;
|
||||||
};
|
};
|
||||||
PackHeader ph; // must be filled by canUnpack(); also used by UiPacker
|
PackHeader ph; // must be filled by canUnpack(); also used by UiPacker
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -178,9 +178,11 @@ PackerBase *PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const O
|
|||||||
VISIT(PackVmlinuxPPC64LE);
|
VISIT(PackVmlinuxPPC64LE);
|
||||||
VISIT(PackVmlinuxAMD64);
|
VISIT(PackVmlinuxAMD64);
|
||||||
VISIT(PackVmlinuxI386);
|
VISIT(PackVmlinuxI386);
|
||||||
|
#if (WITH_ZLIB)
|
||||||
VISIT(PackVmlinuzI386);
|
VISIT(PackVmlinuzI386);
|
||||||
VISIT(PackBvmlinuzI386);
|
VISIT(PackBvmlinuzI386);
|
||||||
VISIT(PackVmlinuzARMEL);
|
VISIT(PackVmlinuzARMEL);
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// linux
|
// linux
|
||||||
|
|||||||
+1
-3
@@ -2179,8 +2179,6 @@ unsigned PeFile::handleStripRelocs(upx_uint64_t ih_imagebase, upx_uint64_t defau
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned umax(unsigned a, unsigned b) { return (a >= b) ? a : b; }
|
|
||||||
|
|
||||||
unsigned PeFile::readSections(unsigned objs, unsigned usize, unsigned ih_filealign,
|
unsigned PeFile::readSections(unsigned objs, unsigned usize, unsigned ih_filealign,
|
||||||
unsigned ih_datasize) {
|
unsigned ih_datasize) {
|
||||||
const unsigned xtrasize = UPX_MAX(ih_datasize, 65536u) + IDSIZE(PEDIR_IMPORT) +
|
const unsigned xtrasize = UPX_MAX(ih_datasize, 65536u) + IDSIZE(PEDIR_IMPORT) +
|
||||||
@@ -2224,7 +2222,7 @@ unsigned PeFile::readSections(unsigned objs, unsigned usize, unsigned ih_fileali
|
|||||||
if (isection[ic].vaddr + jc > ibuf.getSize())
|
if (isection[ic].vaddr + jc > ibuf.getSize())
|
||||||
throwInternalError("buffer too small 1");
|
throwInternalError("buffer too small 1");
|
||||||
fi->readx(ibuf.subref("bad section %#x", isection[ic].vaddr, jc), jc);
|
fi->readx(ibuf.subref("bad section %#x", isection[ic].vaddr, jc), jc);
|
||||||
ibufgood = umax(ibufgood, jc + isection[ic].vaddr); // FIXME: simplistic
|
ibufgood = upx::umax(ibufgood, jc + isection[ic].vaddr); // FIXME: simplistic
|
||||||
jc += isection[ic].rawdataptr;
|
jc += isection[ic].rawdataptr;
|
||||||
}
|
}
|
||||||
return overlaystart;
|
return overlaystart;
|
||||||
|
|||||||
+58
-1
@@ -142,7 +142,7 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// type_traits
|
// <type_traits>
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
// is_bounded_array: identical to C++20 std::is_bounded_array
|
// is_bounded_array: identical to C++20 std::is_bounded_array
|
||||||
@@ -163,6 +163,63 @@ struct is_same_any : public std::disjunction<std::is_same<T, Ts>...> {};
|
|||||||
template <class T, class... Ts>
|
template <class T, class... Ts>
|
||||||
inline constexpr bool is_same_any_v = is_same_any<T, Ts...>::value;
|
inline constexpr bool is_same_any_v = is_same_any<T, Ts...>::value;
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// <bit> C++20
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
forceinline constexpr bool has_single_bit(T x) noexcept {
|
||||||
|
return x != 0 && (x & (x - 1)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// <algorithm>
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T align_down(const T &x, const T &alignment) noexcept {
|
||||||
|
assert_noexcept(has_single_bit(alignment));
|
||||||
|
T r;
|
||||||
|
r = (x / alignment) * alignment;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
inline T align_up(const T &x, const T &alignment) noexcept {
|
||||||
|
assert_noexcept(has_single_bit(alignment));
|
||||||
|
T r;
|
||||||
|
r = ((x + (alignment - 1)) / alignment) * alignment;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
inline T align_gap(const T &x, const T &alignment) noexcept {
|
||||||
|
assert_noexcept(has_single_bit(alignment));
|
||||||
|
T r;
|
||||||
|
r = align_up(x, alignment) - x;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
forceinline constexpr T min(const T &a, const T &b) noexcept {
|
||||||
|
return b < a ? b : a;
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
forceinline constexpr T max(const T &a, const T &b) noexcept {
|
||||||
|
return a < b ? b : a;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline constexpr bool is_uminmax_type =
|
||||||
|
is_same_any_v<T, upx_uint16_t, upx_uint32_t, upx_uint64_t, unsigned long, size_t>;
|
||||||
|
|
||||||
|
template <class T, class = std::enable_if_t<is_uminmax_type<T>, T> >
|
||||||
|
forceinline constexpr T umin(const T &a, const T &b) noexcept {
|
||||||
|
return b < a ? b : a;
|
||||||
|
}
|
||||||
|
template <class T, class = std::enable_if_t<is_uminmax_type<T>, T> >
|
||||||
|
forceinline constexpr T umax(const T &a, const T &b) noexcept {
|
||||||
|
return a < b ? b : a;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// util
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|||||||
@@ -97,8 +97,6 @@ void *MemBuffer::subref_impl(const char *errfmt, size_t skip, size_t take) {
|
|||||||
return ptr + skip;
|
return ptr + skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
static forceinline constexpr size_t umax(size_t a, size_t b) { return (a >= b) ? a : b; }
|
|
||||||
|
|
||||||
/*static*/
|
/*static*/
|
||||||
unsigned MemBuffer::getSizeForCompression(unsigned uncompressed_size, unsigned extra) {
|
unsigned MemBuffer::getSizeForCompression(unsigned uncompressed_size, unsigned extra) {
|
||||||
if (uncompressed_size == 0)
|
if (uncompressed_size == 0)
|
||||||
@@ -106,9 +104,9 @@ unsigned MemBuffer::getSizeForCompression(unsigned uncompressed_size, unsigned e
|
|||||||
const size_t z = uncompressed_size; // fewer keystrokes and display columns
|
const size_t z = uncompressed_size; // fewer keystrokes and display columns
|
||||||
size_t bytes = mem_size(1, z); // check size
|
size_t bytes = mem_size(1, z); // check size
|
||||||
// All literal: 1 bit overhead per literal byte; from UCL documentation
|
// All literal: 1 bit overhead per literal byte; from UCL documentation
|
||||||
bytes = umax(bytes, z + z / 8 + 256);
|
bytes = upx::umax(bytes, z + z / 8 + 256);
|
||||||
// zstd: ZSTD_COMPRESSBOUND
|
// zstd: ZSTD_COMPRESSBOUND
|
||||||
bytes = umax(bytes, z + (z >> 8) + ((z < (128 << 10)) ? (((128 << 10) - z) >> 11) : 0));
|
bytes = upx::umax(bytes, z + (z >> 8) + ((z < (128 << 10)) ? (((128 << 10) - z) >> 11) : 0));
|
||||||
// add extra and 256 safety for various rounding/alignments
|
// add extra and 256 safety for various rounding/alignments
|
||||||
bytes = mem_size(1, bytes, extra, 256);
|
bytes = mem_size(1, bytes, extra, 256);
|
||||||
return ACC_ICONV(unsigned, bytes);
|
return ACC_ICONV(unsigned, bytes);
|
||||||
|
|||||||
@@ -47,6 +47,12 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(NOMINMAX)
|
||||||
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
#define NOMINMAX 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
// disable silly warnings about using "deprecated" POSIX functions like fopen()
|
// disable silly warnings about using "deprecated" POSIX functions like fopen()
|
||||||
#if !defined(_CRT_NONSTDC_NO_DEPRECATE)
|
#if !defined(_CRT_NONSTDC_NO_DEPRECATE)
|
||||||
|
|||||||
@@ -44,18 +44,25 @@
|
|||||||
|
|
||||||
// libc++ hardenining
|
// libc++ hardenining
|
||||||
#if defined(__cplusplus) && 0 // TODO later
|
#if defined(__cplusplus) && 0 // TODO later
|
||||||
|
|
||||||
#if defined(__clang__) && defined(__clang_major__) && (__clang_major__ + 0 >= 18)
|
#if defined(__clang__) && defined(__clang_major__) && (__clang_major__ + 0 >= 18)
|
||||||
|
#if !defined(_LIBCPP_HARDENING_MODE)
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
#define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEBUG
|
#define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEBUG
|
||||||
#else
|
#else
|
||||||
#define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_EXTENSIVE
|
#define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_EXTENSIVE
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif // clang >= 18
|
||||||
|
|
||||||
#if defined(__clang__) && defined(__clang_major__) && (__clang_major__ + 0 < 18)
|
#if defined(__clang__) && defined(__clang_major__) && (__clang_major__ + 0 < 18)
|
||||||
|
#if !defined(_LIBCPP_ENABLE_ASSERTIONS)
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
#define _LIBCPP_ENABLE_ASSERTIONS 1
|
#define _LIBCPP_ENABLE_ASSERTIONS 1
|
||||||
#endif
|
#endif
|
||||||
#endif // clang >= 18
|
#endif
|
||||||
|
#endif // clang < 18
|
||||||
|
|
||||||
#endif // TODO later
|
#endif // TODO later
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
Reference in New Issue
Block a user