src: more clang-format

This commit is contained in:
Markus F.X.J. Oberhumer 2023-10-05 11:53:02 +02:00
parent 632c7c4826
commit e767461f65
23 changed files with 733 additions and 1191 deletions

View File

@ -59,7 +59,7 @@ build/%/all: $$(dir $$@)debug $$(dir $$@)release ;
include ./misc/make/Makefile-extra.mk include ./misc/make/Makefile-extra.mk
# developer convenience # developer convenience
ifeq ($(shell uname),Linux) # needs bash, perl, xargs, etc. ifneq ($(wildcard /usr/bin/env),) # needs bash, perl, xargs, etc.
check-whitespace clang-format run-testsuite run-testsuite-debug run-testsuite-release: PHONY src/Makefile check-whitespace clang-format run-testsuite run-testsuite-debug run-testsuite-release: PHONY src/Makefile
$(MAKE) -C src $@ $(MAKE) -C src $@
endif endif

View File

@ -80,10 +80,9 @@ endif
# automatically format some C++ source code files # automatically format some C++ source code files
ifeq ($(shell uname),Linux) ifeq ($(shell uname),Linux)
# Markus loves clang-format, but John hates it; find a compromise # Markus loves clang-format, but John hates it; find a compromise
CLANG_FORMAT_EXCLUDE_FILES += conf.h miniacc.h version.h packer_c.cpp CLANG_FORMAT_EXCLUDE_FILES += conf.h miniacc.h stub/%.h
CLANG_FORMAT_EXCLUDE_FILES += p_elf.h p_elf_enum.h p_lx_% p_mach% p_unix% p_vmlin% CLANG_FORMAT_EXCLUDE_FILES += p_elf.h p_elf_enum.h p_lx_% p_mach% p_unix% p_vmlin%
CLANG_FORMAT_EXCLUDE_FILES += compress/compress.h filter/filter_impl.cpp CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* */*.[ch]*))
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* [cu]*/*.[ch]*))
CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES)) CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES))
clang-format: PHONY $(CLANG_FORMAT_FILES) clang-format: PHONY $(CLANG_FORMAT_FILES)
@echo "running upx-clang-format" @echo "running upx-clang-format"
@ -94,7 +93,7 @@ endif
# "make check-whitespace" # "make check-whitespace"
# #
ifeq ($(shell uname),Linux) # needs bash, perl, xargs, etc. ifneq ($(wildcard /usr/bin/env),) # needs bash, perl, xargs, etc.
CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace.sh $(top_srcdir) CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace.sh $(top_srcdir)
ifneq ($(wildcard $(top_srcdir)/.git/.),) ifneq ($(wildcard $(top_srcdir)/.git/.),)
CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir) CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir)

View File

@ -25,8 +25,8 @@
*/ */
#pragma once #pragma once
#ifndef UPX_COMPRESS_H__
#define UPX_COMPRESS_H__ 1 // clang-format off
/************************************************************************* /*************************************************************************
// //
@ -53,7 +53,6 @@ int upx_bzip2_test_overlap ( const upx_bytep buf,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
#if (WITH_LZMA) #if (WITH_LZMA)
int upx_lzma_init(void); int upx_lzma_init(void);
const char *upx_lzma_version_string(void); const char *upx_lzma_version_string(void);
@ -75,7 +74,6 @@ int upx_lzma_test_overlap ( const upx_bytep buf,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
#if (WITH_NRV) #if (WITH_NRV)
int upx_nrv_init(void); int upx_nrv_init(void);
const char *upx_nrv_version_string(void); const char *upx_nrv_version_string(void);
@ -97,7 +95,6 @@ int upx_nrv_test_overlap ( const upx_bytep buf,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
#if (WITH_UCL) #if (WITH_UCL)
int upx_ucl_init(void); int upx_ucl_init(void);
const char *upx_ucl_version_string(void); const char *upx_ucl_version_string(void);
@ -121,7 +118,6 @@ unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler);
unsigned upx_ucl_crc32 (const void *buf, unsigned len, unsigned crc); unsigned upx_ucl_crc32 (const void *buf, unsigned len, unsigned crc);
#endif #endif
#if (WITH_ZLIB) #if (WITH_ZLIB)
int upx_zlib_init(void); int upx_zlib_init(void);
const char *upx_zlib_version_string(void); const char *upx_zlib_version_string(void);
@ -145,7 +141,6 @@ unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler);
unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc); unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc);
#endif #endif
#if (WITH_ZSTD) #if (WITH_ZSTD)
int upx_zstd_init(void); int upx_zstd_init(void);
const char *upx_zstd_version_string(void); const char *upx_zstd_version_string(void);
@ -167,7 +162,4 @@ int upx_zstd_test_overlap ( const upx_bytep buf,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
#endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */

View File

@ -765,6 +765,7 @@ void show_version(bool one_line=false);
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1); unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc=0); unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc=0);
// clang-format off
int upx_compress ( const upx_bytep src, unsigned src_len, int upx_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned* dst_len,
upx_callback_p cb, upx_callback_p cb,
@ -781,6 +782,7 @@ int upx_test_overlap ( const upx_bytep buf,
unsigned* dst_len, unsigned* dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
// clang-format on
#include "util/snprintf.h" // must get included first! #include "util/snprintf.h" // must get included first!

View File

@ -52,18 +52,21 @@
throwIOException("rename error", errno); throwIOException("rename error", errno);
} }
/*static*/ bool FileBase::unlink(const char *name, bool check) { /*static*/ bool FileBase::unlink_noexcept(const char *name) noexcept {
assert(name != nullptr && name[0] != 0); assert_noexcept(name != nullptr && name[0] != 0);
bool success = ::unlink(name) == 0; bool success = ::unlink(name) == 0;
#if HAVE_CHMOD #if HAVE_CHMOD
if (!success) if (!success)
success = (::chmod(name, 0666) == 0 && ::unlink(name) == 0); success = (::chmod(name, 0666) == 0 && ::unlink(name) == 0);
#endif #endif
if (check && !success)
throwIOException(name, errno);
return success; return success;
} }
/*static*/ void FileBase::unlink(const char *name) {
if (!unlink_noexcept(name))
throwIOException(name, errno);
}
/************************************************************************* /*************************************************************************
// FileBase // FileBase
**************************************************************************/ **************************************************************************/

View File

@ -52,7 +52,8 @@ public:
// static file-related util functions; will throw on error // static file-related util functions; will throw on error
static void chmod(const char *name, int mode) may_throw; static void chmod(const char *name, int mode) may_throw;
static void rename(const char *old_, const char *new_) may_throw; static void rename(const char *old_, const char *new_) may_throw;
static bool unlink(const char *name, bool check = true) may_throw; static void unlink(const char *name) may_throw;
static bool unlink_noexcept(const char *name) noexcept;
protected: protected:
bool do_sopen(); bool do_sopen();

View File

@ -25,434 +25,325 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// 16-bit calltrick ("naive") // 16-bit calltrick ("naive")
**************************************************************************/ **************************************************************************/
#define CT16(f, cond, addvalue, get, set) \ #define CT16(f, cond, addvalue, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 3; \ byte *b_end = b + f->buf_len - 3; \
do { \ do { \
if (cond) \ if (cond) { \
{ \ b += 1; \
b += 1; \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b) + (addvalue)); \
set(b, get(b) + (addvalue)); \ f->calls++; \
f->calls++; \ b += 2 - 1; \
b += 2 - 1; \ } \
} \ } while (++b < b_end); \
} while (++b < b_end); \ if (f->lastcall) \
if (f->lastcall) f->lastcall += 2; \ f->lastcall += 2; \
return 0; return 0;
// filter: e8, e9, e8e9 // filter: e8, e9, e8e9
static int f_ct16_e8(Filter *f) static int f_ct16_e8(Filter *f) { CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_le16) }
{
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_le16)
}
static int f_ct16_e9(Filter *f) static int f_ct16_e9(Filter *f) { CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_le16) }
{
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_le16)
}
static int f_ct16_e8e9(Filter *f) static int f_ct16_e8e9(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_le16) CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_le16)
} }
// unfilter: e8, e9, e8e9 // unfilter: e8, e9, e8e9
static int u_ct16_e8(Filter *f) static int u_ct16_e8(Filter *f) { CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_le16, set_le16) }
{
CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_le16, set_le16)
}
static int u_ct16_e9(Filter *f) static int u_ct16_e9(Filter *f) { CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_le16, set_le16) }
{
CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_le16, set_le16)
}
static int u_ct16_e8e9(Filter *f) static int u_ct16_e8e9(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le16, set_le16) CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le16, set_le16)
} }
// scan: e8, e9, e8e9 // scan: e8, e9, e8e9
static int s_ct16_e8(Filter *f) static int s_ct16_e8(Filter *f) { CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_dummy) }
{
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_dummy)
}
static int s_ct16_e9(Filter *f) static int s_ct16_e9(Filter *f) { CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_dummy) }
{
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_dummy)
}
static int s_ct16_e8e9(Filter *f) static int s_ct16_e8e9(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_dummy) CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_dummy)
} }
// filter: e8, e9, e8e9 with bswap le->be // filter: e8, e9, e8e9 with bswap le->be
static int f_ct16_e8_bswap_le(Filter *f) static int f_ct16_e8_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_be16) CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_be16)
} }
static int f_ct16_e9_bswap_le(Filter *f) static int f_ct16_e9_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_be16) CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_be16)
} }
static int f_ct16_e8e9_bswap_le(Filter *f) static int f_ct16_e8e9_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_be16) CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_be16)
} }
// unfilter: e8, e9, e8e9 with bswap le->be // unfilter: e8, e9, e8e9 with bswap le->be
static int u_ct16_e8_bswap_le(Filter *f) static int u_ct16_e8_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_be16, set_le16) CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_be16, set_le16)
} }
static int u_ct16_e9_bswap_le(Filter *f) static int u_ct16_e9_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16) CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16)
} }
static int u_ct16_e8e9_bswap_le(Filter *f) static int u_ct16_e8e9_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16) CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16)
} }
// scan: e8, e9, e8e9 with bswap le->be // scan: e8, e9, e8e9 with bswap le->be
static int s_ct16_e8_bswap_le(Filter *f) static int s_ct16_e8_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe8), a + f->addvalue, get_be16, set_dummy) CT16(f, (*b == 0xe8), a + f->addvalue, get_be16, set_dummy)
} }
static int s_ct16_e9_bswap_le(Filter *f) static int s_ct16_e9_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe9), a + f->addvalue, get_be16, set_dummy) CT16(f, (*b == 0xe9), a + f->addvalue, get_be16, set_dummy)
} }
static int s_ct16_e8e9_bswap_le(Filter *f) static int s_ct16_e8e9_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be16, set_dummy) CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be16, set_dummy)
} }
// filter: e8, e9, e8e9 with bswap be->le // filter: e8, e9, e8e9 with bswap be->le
static int f_ct16_e8_bswap_be(Filter *f) static int f_ct16_e8_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe8), a + f->addvalue, get_be16, set_le16) CT16(f, (*b == 0xe8), a + f->addvalue, get_be16, set_le16)
} }
static int f_ct16_e9_bswap_be(Filter *f) static int f_ct16_e9_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe9), a + f->addvalue, get_be16, set_le16) CT16(f, (*b == 0xe9), a + f->addvalue, get_be16, set_le16)
} }
static int f_ct16_e8e9_bswap_be(Filter *f) static int f_ct16_e8e9_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be16, set_le16) CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be16, set_le16)
} }
// unfilter: e8, e9, e8e9 with bswap be->le // unfilter: e8, e9, e8e9 with bswap be->le
static int u_ct16_e8_bswap_be(Filter *f) static int u_ct16_e8_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_le16, set_be16) CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_le16, set_be16)
} }
static int u_ct16_e9_bswap_be(Filter *f) static int u_ct16_e9_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_le16, set_be16) CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_le16, set_be16)
} }
static int u_ct16_e8e9_bswap_be(Filter *f) static int u_ct16_e8e9_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le16, set_be16) CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le16, set_be16)
} }
// scan: e8, e9, e8e9 with bswap be->le // scan: e8, e9, e8e9 with bswap be->le
static int s_ct16_e8_bswap_be(Filter *f) static int s_ct16_e8_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_dummy) CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_dummy)
} }
static int s_ct16_e9_bswap_be(Filter *f) static int s_ct16_e9_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_dummy) CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_dummy)
} }
static int s_ct16_e8e9_bswap_be(Filter *f) static int s_ct16_e8e9_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_dummy) CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_dummy)
} }
#undef CT16 #undef CT16
/************************************************************************* /*************************************************************************
// 32-bit calltrick ("naive") // 32-bit calltrick ("naive")
**************************************************************************/ **************************************************************************/
#define CT32(f, cond, addvalue, get, set) \ #define CT32(f, cond, addvalue, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 5; \ byte *b_end = b + f->buf_len - 5; \
do { \ do { \
if (cond) \ if (cond) { \
{ \ b += 1; \
b += 1; \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b) + (addvalue)); \
set(b, get(b) + (addvalue)); \ f->calls++; \
f->calls++; \ b += 4 - 1; \
b += 4 - 1; \ } \
} \ } while (++b < b_end); \
} while (++b < b_end); \ if (f->lastcall) \
if (f->lastcall) f->lastcall += 4; \ f->lastcall += 4; \
return 0; return 0;
// filter: e8, e9, e8e9 // filter: e8, e9, e8e9
static int f_ct32_e8(Filter *f) static int f_ct32_e8(Filter *f) { CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_le32) }
{
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_le32)
}
static int f_ct32_e9(Filter *f) static int f_ct32_e9(Filter *f) { CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_le32) }
{
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_le32)
}
static int f_ct32_e8e9(Filter *f) static int f_ct32_e8e9(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_le32) CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_le32)
} }
// unfilter: e8, e9, e8e9 // unfilter: e8, e9, e8e9
static int u_ct32_e8(Filter *f) static int u_ct32_e8(Filter *f) { CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_le32, set_le32) }
{
CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_le32, set_le32)
}
static int u_ct32_e9(Filter *f) static int u_ct32_e9(Filter *f) { CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_le32, set_le32) }
{
CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_le32, set_le32)
}
static int u_ct32_e8e9(Filter *f) static int u_ct32_e8e9(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le32, set_le32) CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le32, set_le32)
} }
// scan: e8, e9, e8e9 // scan: e8, e9, e8e9
static int s_ct32_e8(Filter *f) static int s_ct32_e8(Filter *f) { CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_dummy) }
{
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_dummy)
}
static int s_ct32_e9(Filter *f) static int s_ct32_e9(Filter *f) { CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_dummy) }
{
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_dummy)
}
static int s_ct32_e8e9(Filter *f) static int s_ct32_e8e9(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_dummy) CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_dummy)
} }
// filter: e8, e9, e8e9 with bswap le->be // filter: e8, e9, e8e9 with bswap le->be
static int f_ct32_e8_bswap_le(Filter *f) static int f_ct32_e8_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_be32) CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_be32)
} }
static int f_ct32_e9_bswap_le(Filter *f) static int f_ct32_e9_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_be32) CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_be32)
} }
static int f_ct32_e8e9_bswap_le(Filter *f) static int f_ct32_e8e9_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_be32) CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_be32)
} }
// unfilter: e8, e9, e8e9 with bswap le->be // unfilter: e8, e9, e8e9 with bswap le->be
static int u_ct32_e8_bswap_le(Filter *f) static int u_ct32_e8_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_be32, set_le32) CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_be32, set_le32)
} }
static int u_ct32_e9_bswap_le(Filter *f) static int u_ct32_e9_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32) CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32)
} }
static int u_ct32_e8e9_bswap_le(Filter *f) static int u_ct32_e8e9_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32) CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32)
} }
// scan: e8, e9, e8e9 with bswap le->be // scan: e8, e9, e8e9 with bswap le->be
static int s_ct32_e8_bswap_le(Filter *f) static int s_ct32_e8_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe8), a + f->addvalue, get_be32, set_dummy) CT32(f, (*b == 0xe8), a + f->addvalue, get_be32, set_dummy)
} }
static int s_ct32_e9_bswap_le(Filter *f) static int s_ct32_e9_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe9), a + f->addvalue, get_be32, set_dummy) CT32(f, (*b == 0xe9), a + f->addvalue, get_be32, set_dummy)
} }
static int s_ct32_e8e9_bswap_le(Filter *f) static int s_ct32_e8e9_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be32, set_dummy) CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be32, set_dummy)
} }
// filter: e8, e9, e8e9 with bswap be->le // filter: e8, e9, e8e9 with bswap be->le
static int f_ct32_e8_bswap_be(Filter *f) static int f_ct32_e8_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe8), a + f->addvalue, get_be32, set_le32) CT32(f, (*b == 0xe8), a + f->addvalue, get_be32, set_le32)
} }
static int f_ct32_e9_bswap_be(Filter *f) static int f_ct32_e9_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe9), a + f->addvalue, get_be32, set_le32) CT32(f, (*b == 0xe9), a + f->addvalue, get_be32, set_le32)
} }
static int f_ct32_e8e9_bswap_be(Filter *f) static int f_ct32_e8e9_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be32, set_le32) CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be32, set_le32)
} }
// unfilter: e8, e9, e8e9 with bswap be->le // unfilter: e8, e9, e8e9 with bswap be->le
static int u_ct32_e8_bswap_be(Filter *f) static int u_ct32_e8_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_le32, set_be32) CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_le32, set_be32)
} }
static int u_ct32_e9_bswap_be(Filter *f) static int u_ct32_e9_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_le32, set_be32) CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_le32, set_be32)
} }
static int u_ct32_e8e9_bswap_be(Filter *f) static int u_ct32_e8e9_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le32, set_be32) CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le32, set_be32)
} }
// scan: e8, e9, e8e9 with bswap be->le // scan: e8, e9, e8e9 with bswap be->le
static int s_ct32_e8_bswap_be(Filter *f) static int s_ct32_e8_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_dummy) CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_dummy)
} }
static int s_ct32_e9_bswap_be(Filter *f) static int s_ct32_e9_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_dummy) CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_dummy)
} }
static int s_ct32_e8e9_bswap_be(Filter *f) static int s_ct32_e8e9_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_dummy) CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_dummy)
} }
#undef CT32 #undef CT32
/************************************************************************* /*************************************************************************
// 24-bit ARM calltrick ("naive") // 24-bit ARM calltrick ("naive")
**************************************************************************/ **************************************************************************/
#define CT24ARM_LE(f, cond, addvalue, get, set) \ #define CT24ARM_LE(f, cond, addvalue, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 4; \ byte *b_end = b + f->buf_len - 4; \
do { \ do { \
if (cond) \ if (cond) { \
{ \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b) + (addvalue)); \
set(b, get(b) + (addvalue)); \ f->calls++; \
f->calls++; \ } \
} \ b += 4; \
b += 4; \ } while (b < b_end); \
} while (b < b_end); \ if (f->lastcall) \
if (f->lastcall) f->lastcall += 4; \ f->lastcall += 4; \
return 0; return 0;
#define ARMCT_COND_le (((b[3] & 0x0f) == 0x0b)) #define ARMCT_COND_le (((b[3] & 0x0f) == 0x0b))
static int f_ct24arm_le(Filter *f) static int f_ct24arm_le(Filter *f) {
{
CT24ARM_LE(f, ARMCT_COND_le, a / 4 + f->addvalue, get_le24, set_le24) CT24ARM_LE(f, ARMCT_COND_le, a / 4 + f->addvalue, get_le24, set_le24)
} }
static int u_ct24arm_le(Filter *f) static int u_ct24arm_le(Filter *f) {
{
CT24ARM_LE(f, ARMCT_COND_le, 0 - a / 4 - f->addvalue, get_le24, set_le24) CT24ARM_LE(f, ARMCT_COND_le, 0 - a / 4 - f->addvalue, get_le24, set_le24)
} }
static int s_ct24arm_le(Filter *f) static int s_ct24arm_le(Filter *f) {
{
CT24ARM_LE(f, ARMCT_COND_le, a + f->addvalue, get_le24, set_dummy) CT24ARM_LE(f, ARMCT_COND_le, a + f->addvalue, get_le24, set_dummy)
} }
#undef CT24ARM_LE #undef CT24ARM_LE
#define CT24ARM_BE(f, cond, addvalue, get, set) \ #define CT24ARM_BE(f, cond, addvalue, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 4; \ byte *b_end = b + f->buf_len - 4; \
do { \ do { \
if (cond) \ if (cond) { \
{ \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(1 + b, get(1 + b) + (addvalue)); \
set(1+b, get(1+b) + (addvalue)); \ f->calls++; \
f->calls++; \ } \
} \ b += 4; \
b += 4; \ } while (b < b_end); \
} while (b < b_end); \ if (f->lastcall) \
if (f->lastcall) f->lastcall += 4; \ f->lastcall += 4; \
return 0; return 0;
#define ARMCT_COND_be (((b[0] & 0x0f) == 0x0b)) #define ARMCT_COND_be (((b[0] & 0x0f) == 0x0b))
static int f_ct24arm_be(Filter *f) static int f_ct24arm_be(Filter *f) {
{
CT24ARM_BE(f, ARMCT_COND_be, a / 4 + f->addvalue, get_be24, set_be24) CT24ARM_BE(f, ARMCT_COND_be, a / 4 + f->addvalue, get_be24, set_be24)
} }
static int u_ct24arm_be(Filter *f) static int u_ct24arm_be(Filter *f) {
{
CT24ARM_BE(f, ARMCT_COND_be, 0 - a / 4 - f->addvalue, get_be24, set_be24) CT24ARM_BE(f, ARMCT_COND_be, 0 - a / 4 - f->addvalue, get_be24, set_be24)
} }
static int s_ct24arm_be(Filter *f) static int s_ct24arm_be(Filter *f) {
{
CT24ARM_BE(f, ARMCT_COND_be, a + f->addvalue, get_be24, set_dummy) CT24ARM_BE(f, ARMCT_COND_be, a + f->addvalue, get_be24, set_dummy)
} }
@ -463,89 +354,79 @@ static int s_ct24arm_be(Filter *f)
// 26-bit ARM calltrick ("naive") // 26-bit ARM calltrick ("naive")
**************************************************************************/ **************************************************************************/
#if 1 //{ old reliable #if 1 //{ old reliable
#define CT26ARM_LE(f, cond, addvalue, get, set) \ #define CT26ARM_LE(f, cond, addvalue, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 4; \ byte *b_end = b + f->buf_len - 4; \
do { \ do { \
if (cond) \ if (cond) { \
{ \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b) + (addvalue)); \
set(b, get(b) + (addvalue)); \ f->calls++; \
f->calls++; \ } \
} \ b += 4; \
b += 4; \ } while (b < b_end); \
} while (b < b_end); \ if (f->lastcall) \
if (f->lastcall) f->lastcall += 4; \ f->lastcall += 4; \
return 0; return 0;
#define ARMCT_COND (((b[3] & 0x7C) == 0x14)) #define ARMCT_COND (((b[3] & 0x7C) == 0x14))
static int f_ct26arm_le(Filter *f) static int f_ct26arm_le(Filter *f) {
{
CT26ARM_LE(f, ARMCT_COND, a / 4 + f->addvalue, get_le26, set_le26) CT26ARM_LE(f, ARMCT_COND, a / 4 + f->addvalue, get_le26, set_le26)
} }
static int u_ct26arm_le(Filter *f) static int u_ct26arm_le(Filter *f) {
{
CT26ARM_LE(f, ARMCT_COND, 0 - a / 4 - f->addvalue, get_le26, set_le26) CT26ARM_LE(f, ARMCT_COND, 0 - a / 4 - f->addvalue, get_le26, set_le26)
} }
static int s_ct26arm_le(Filter *f) static int s_ct26arm_le(Filter *f) {
{
CT26ARM_LE(f, ARMCT_COND, a + f->addvalue, get_le26, set_dummy) CT26ARM_LE(f, ARMCT_COND, a + f->addvalue, get_le26, set_dummy)
} }
#else //}{ new enhanced but DIFFERENT; need new filter type! #else //}{ new enhanced but DIFFERENT; need new filter type!
static int CTarm64(Filter *f, int dir) // dir: 1, 0, -1 static int CTarm64(Filter *f, int dir) // dir: 1, 0, -1
{ {
upx_byte *b = f->buf; // will be incremented upx_byte *b = f->buf; // will be incremented
upx_byte *const b_end = b + f->buf_len - 4; upx_byte *const b_end = b + f->buf_len - 4;
do { do {
unsigned const a = b - f->buf; unsigned const a = b - f->buf;
int const d = dir * (f->addvalue + (a >> 2)); int const d = dir * (f->addvalue + (a >> 2));
unsigned const v = get_le32(f->buf); // the 32-bit instruction unsigned const v = get_le32(f->buf); // the 32-bit instruction
if (0x05 == (0x1f & (v >> 26))) { // b, bl if (0x05 == (0x1f & (v >> 26))) { // b, bl
f->lastcall = a; f->lastcall = a;
if (dir) set_le26(b, v + d); if (dir)
set_le26(b, v + d);
f->calls++; f->calls++;
} } else if ((0x54 == (v >> 24)) // b.cond
else if ( (0x54 == (v >> 24) ) // b.cond || (0x1a == ((v >> 25) & 0x3f)) // cb{z,nz}
|| (0x1a == ((v >> 25) & 0x3f)) // cb{z,nz} ) {
) {
f->lastcall = a; f->lastcall = a;
if (dir) set_le19_5(b, (v >> 5) + d); if (dir)
set_le19_5(b, (v >> 5) + d);
f->calls++; f->calls++;
} } else if (0x1b == ((v >> 25) & 0x3f)) { // tb{z,nz}
else if (0x1b == ((v >> 25) & 0x3f)) { // tb{z,nz}
f->lastcall = a; f->lastcall = a;
if (dir) set_le14_5(b, (v >> 5) + d); if (dir)
set_le14_5(b, (v >> 5) + d);
f->calls++; f->calls++;
} }
b += 4; b += 4;
} while (b < b_end); } while (b < b_end);
if (f->lastcall) f->lastcall += 4; if (f->lastcall)
f->lastcall += 4;
return 0; return 0;
} }
static int f_CTarm64_le(Filter *f) static int f_CTarm64_le(Filter *f) { return CTarm64(f, 1); }
{
return CTarm64(f, 1);
}
static int u_CTarm64_le(Filter *f) static int u_CTarm64_le(Filter *f) { return CTarm64(f, -1); }
{
return CTarm64(f, -1);
}
static int s_CTarm64_le(Filter *f) static int s_CTarm64_le(Filter *f) { return CTarm64(f, 0); }
{
return CTarm64(f, 0);
}
#endif //} #endif //}
#undef CT26ARM_LE #undef CT26ARM_LE
#undef ARMCT_COND #undef ARMCT_COND

View File

@ -25,14 +25,11 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// filter / scan // filter / scan
**************************************************************************/ **************************************************************************/
static int F(Filter *f) static int F(Filter *f) {
{
#ifdef U #ifdef U
// filter // filter
byte *b = f->buf; byte *b = f->buf;
@ -50,25 +47,22 @@ static int F(Filter *f)
// find a 16 MiB large empty address space // find a 16 MiB large empty address space
{ {
unsigned char buf[256]; unsigned char buf[256];
memset(buf,0,256); memset(buf, 0, 256);
// A call to a destination that is inside the buffer // A call to a destination that is inside the buffer
// will be rewritten and marked with cto8 as first byte. // will be rewritten and marked with cto8 as first byte.
// So, a call to a destination that is outside the buffer // So, a call to a destination that is outside the buffer
// must not conflict with the mark. // must not conflict with the mark.
// Note that unsigned comparison checks both edges of buffer. // Note that unsigned comparison checks both edges of buffer.
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++) {
{ if (!COND(b, ic))
if (!COND(b,ic))
continue; continue;
jc = get_le32(b+ic+1)+ic+1; jc = get_le32(b + ic + 1) + ic + 1;
if (jc < size) if (jc < size) {
{
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8 if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
return -1; return -1;
} } else
else buf[b[ic + 1]] |= 1;
buf[b[ic+1]] |= 1;
} }
if (getcto(f, buf) < 0) if (getcto(f, buf) < 0)
@ -76,35 +70,31 @@ static int F(Filter *f)
} }
const unsigned char cto8 = f->cto; const unsigned char cto8 = f->cto;
#ifdef U #ifdef U
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
#endif #endif
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++) {
{ if (!COND(b, ic))
if (!COND(b,ic))
continue; continue;
jc = get_le32(b+ic+1)+ic+1; jc = get_le32(b + ic + 1) + ic + 1;
// try to detect 'real' calls only // try to detect 'real' calls only
if (jc < size) if (jc < size) {
{
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8 assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
#ifdef U #ifdef U
set_be32(b+ic+1,jc+addvalue+cto); set_be32(b + ic + 1, jc + addvalue + cto);
#endif #endif
if (ic - lastnoncall < 5) if (ic - lastnoncall < 5) {
{
// check the last 4 bytes before this call // check the last 4 bytes before this call
for (kc = 4; kc; kc--) for (kc = 4; kc; kc--)
if (COND(b,ic-kc) && b[ic-kc+1] == cto8) if (COND(b, ic - kc) && b[ic - kc + 1] == cto8)
break; break;
if (kc) if (kc) {
{
#ifdef U #ifdef U
// restore original // restore original
set_le32(b+ic+1,jc-ic-1); set_le32(b + ic + 1, jc - ic - 1);
#endif #endif
if (b[ic+1] == cto8) if (b[ic + 1] == cto8)
return 1; // fail - buffer not restored return 1; // fail - buffer not restored
lastnoncall = ic; lastnoncall = ic;
noncalls2++; noncalls2++;
continue; continue;
@ -112,11 +102,9 @@ static int F(Filter *f)
} }
calls++; calls++;
ic += 4; ic += 4;
lastcall = ic+1; lastcall = ic + 1;
} } else {
else assert(b[ic + 1] != cto8); // this should not happen
{
assert(b[ic+1] != cto8); // this should not happen
lastnoncall = ic; lastnoncall = ic;
noncalls++; noncalls++;
} }
@ -133,40 +121,34 @@ static int F(Filter *f)
return 0; return 0;
} }
/************************************************************************* /*************************************************************************
// unfilter // unfilter
**************************************************************************/ **************************************************************************/
#ifdef U #ifdef U
static int U(Filter *f) static int U(Filter *f) {
{
byte *b = f->buf; byte *b = f->buf;
const unsigned size5 = f->buf_len - 5; const unsigned size5 = f->buf_len - 5;
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
unsigned ic, jc; unsigned ic, jc;
for (ic = 0; ic < size5; ic++) for (ic = 0; ic < size5; ic++)
if (COND(b,ic)) if (COND(b, ic)) {
{ jc = get_be32(b + ic + 1);
jc = get_be32(b+ic+1); if (b[ic + 1] == f->cto) {
if (b[ic+1] == f->cto) set_le32(b + ic + 1, jc - ic - 1 - addvalue - cto);
{
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
f->calls++; f->calls++;
ic += 4; ic += 4;
f->lastcall = ic+1; f->lastcall = ic + 1;
} } else
else
f->noncalls++; f->noncalls++;
} }
return 0; return 0;
} }
#endif #endif
#undef F #undef F
#undef U #undef U

View File

@ -29,14 +29,11 @@
<jreiser@users.sourceforge.net> <jreiser@users.sourceforge.net>
*/ */
/************************************************************************* /*************************************************************************
// filter / scan // filter / scan
**************************************************************************/ **************************************************************************/
static int F(Filter *f) static int F(Filter *f) {
{
#ifdef U #ifdef U
// filter // filter
byte *b = f->buf; byte *b = f->buf;
@ -54,20 +51,17 @@ static int F(Filter *f)
// find a 16 MiB large empty address space // find a 16 MiB large empty address space
{ {
unsigned char buf[256]; unsigned char buf[256];
memset(buf,0,256); memset(buf, 0, 256);
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++) {
{ if (!COND(b, ic, lastcall))
if (!COND(b,ic,lastcall))
continue; continue;
jc = get_le32(b+ic+1)+ic+1; jc = get_le32(b + ic + 1) + ic + 1;
if (jc < size) if (jc < size) {
{
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8 if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
return -1; return -1;
} } else
else buf[b[ic + 1]] |= 1;
buf[b[ic+1]] |= 1;
} }
if (getcto(f, buf) < 0) if (getcto(f, buf) < 0)
@ -75,35 +69,31 @@ static int F(Filter *f)
} }
const unsigned char cto8 = f->cto; const unsigned char cto8 = f->cto;
#ifdef U #ifdef U
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
#endif #endif
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++) {
{ if (!COND(b, ic, lastcall))
if (!COND(b,ic,lastcall))
continue; continue;
jc = get_le32(b+ic+1)+ic+1; jc = get_le32(b + ic + 1) + ic + 1;
// try to detect 'real' calls only // try to detect 'real' calls only
if (jc < size) if (jc < size) {
{
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8 assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
#ifdef U #ifdef U
set_be32(b+ic+1,jc+addvalue+cto); set_be32(b + ic + 1, jc + addvalue + cto);
#endif #endif
if (ic - lastnoncall < 5) if (ic - lastnoncall < 5) {
{
// check the last 4 bytes before this call // check the last 4 bytes before this call
for (kc = 4; kc; kc--) for (kc = 4; kc; kc--)
if (COND(b,ic-kc,lastcall) && b[ic-kc+1] == cto8) if (COND(b, ic - kc, lastcall) && b[ic - kc + 1] == cto8)
break; break;
if (kc) if (kc) {
{
#ifdef U #ifdef U
// restore original // restore original
set_le32(b+ic+1,jc-ic-1); set_le32(b + ic + 1, jc - ic - 1);
#endif #endif
if (b[ic+1] == cto8) if (b[ic + 1] == cto8)
return 1; // fail - buffer not restored return 1; // fail - buffer not restored
lastnoncall = ic; lastnoncall = ic;
noncalls2++; noncalls2++;
continue; continue;
@ -111,11 +101,9 @@ static int F(Filter *f)
} }
calls++; calls++;
ic += 4; ic += 4;
lastcall = ic+1; lastcall = ic + 1;
} } else {
else assert(b[ic + 1] != cto8); // this should not happen
{
assert(b[ic+1] != cto8); // this should not happen
lastnoncall = ic; lastnoncall = ic;
noncalls++; noncalls++;
} }
@ -132,40 +120,34 @@ static int F(Filter *f)
return 0; return 0;
} }
/************************************************************************* /*************************************************************************
// unfilter // unfilter
**************************************************************************/ **************************************************************************/
#ifdef U #ifdef U
static int U(Filter *f) static int U(Filter *f) {
{
byte *b = f->buf; byte *b = f->buf;
const unsigned size5 = f->buf_len - 5; const unsigned size5 = f->buf_len - 5;
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
// unsigned lastcall = 0; // lastcall is not used in COND macro // unsigned lastcall = 0; // lastcall is not used in COND macro
unsigned ic, jc; unsigned ic, jc;
for (ic = 0; ic < size5; ic++) for (ic = 0; ic < size5; ic++)
if (COND(b,ic,lastcall)) if (COND(b, ic, lastcall)) {
{ jc = get_be32(b + ic + 1);
jc = get_be32(b+ic+1); if (b[ic + 1] == f->cto) {
if (b[ic+1] == f->cto) set_le32(b + ic + 1, jc - ic - 1 - addvalue - cto);
{
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
f->calls++; f->calls++;
ic += 4; ic += 4;
f->lastcall = ic+1; f->lastcall = ic + 1;
} } else
else
f->noncalls++; f->noncalls++;
} }
return 0; return 0;
} }
#endif #endif
#undef F #undef F
#undef U #undef U

View File

@ -29,61 +29,43 @@
<jreiser@users.sourceforge.net> <jreiser@users.sourceforge.net>
*/ */
#if (ACC_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1300)) #if (ACC_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1300))
# pragma warning(disable: 4702) // W4: unreachable code #pragma warning(disable : 4702) // W4: unreachable code
#endif #endif
/************************************************************************* /*************************************************************************
// filter / scan // filter / scan
**************************************************************************/ **************************************************************************/
#ifdef U //{ #ifdef U //{
#define NOFILT 0 // no filter #define NOFILT 0 // no filter
#define FNOMRU 1 // filter, but not using mru #define FNOMRU 1 // filter, but not using mru
#define MRUFLT 2 // mru filter #define MRUFLT 2 // mru filter
static unsigned static unsigned f80_call(Filter const *f) { return (1 + (0x0f & f->id)) % 3; }
f80_call(Filter const *f)
{
return (1+ (0x0f & f->id)) % 3;
}
static unsigned static unsigned f80_jmp1(Filter const *f) { return ((1 + (0x0f & f->id)) / 3) % 3; }
f80_jmp1(Filter const *f)
{
return ((1+ (0x0f & f->id)) / 3) % 3;
}
static unsigned static unsigned f80_jcc2(Filter const *f) { return f80_jmp1(f); }
f80_jcc2(Filter const *f)
{
return f80_jmp1(f);
}
#define N_MRU 32 // does not have to be a power of 2 #define N_MRU 32 // does not have to be a power of 2
// Adaptively remember recent destinations. // Adaptively remember recent destinations.
static void static void update_mru(const unsigned jc, // destination address
update_mru( const int kh, // mru[kh] is slot where found
const unsigned jc, // destination address unsigned mru[N_MRU], // circular buffer of most recent destinations
const int kh, // mru[kh] is slot where found int &hand, // mru[hand] is most recent destination
unsigned mru[N_MRU], // circular buffer of most recent destinations int &tail // mru[tail] is beyond oldest destination ("cold cache" startup)
int &hand, // mru[hand] is most recent destination ) {
int &tail // mru[tail] is beyond oldest destination ("cold cache" startup)
)
{
if (0 > --hand) { if (0 > --hand) {
hand = N_MRU -1; hand = N_MRU - 1;
} }
const unsigned t = mru[hand]; // entry which will be overwritten by jc const unsigned t = mru[hand]; // entry which will be overwritten by jc
if (0!=t) { // have seen at least N_MRU destinations if (0 != t) { // have seen at least N_MRU destinations
mru[kh] = t; mru[kh] = t;
} } else { // "cold cache": keep active region contiguous
else { // "cold cache": keep active region contiguous
if (0 > --tail) { if (0 > --tail) {
tail = N_MRU -1; tail = N_MRU - 1;
} }
const unsigned t2 = mru[tail]; const unsigned t2 = mru[tail];
mru[tail] = 0; mru[tail] = 0;
@ -91,11 +73,9 @@ update_mru(
} }
mru[hand] = jc; mru[hand] = jc;
} }
#endif //} #endif //}
static int F(Filter *f) {
static int F(Filter *f)
{
#ifdef U #ifdef U
// filter // filter
byte *const b = f->buf; byte *const b = f->buf;
@ -108,9 +88,10 @@ static int F(Filter *f)
unsigned ic, jc, kc; unsigned ic, jc, kc;
unsigned calls = 0, noncalls = 0, noncalls2 = 0; unsigned calls = 0, noncalls = 0, noncalls2 = 0;
unsigned lastnoncall = size, lastcall = 0; unsigned lastnoncall = size, lastcall = 0;
unsigned wtally[3]; memset(wtally, 0, sizeof(wtally)); unsigned wtally[3];
memset(wtally, 0, sizeof(wtally));
#ifdef U //{ #ifdef U //{
const unsigned f_call = f80_call(f); const unsigned f_call = f80_call(f);
const unsigned f_jmp1 = f80_jmp1(f); const unsigned f_jmp1 = f80_jmp1(f);
const unsigned f_jcc2 = f80_jcc2(f); const unsigned f_jcc2 = f80_jcc2(f);
@ -118,22 +99,20 @@ static int F(Filter *f)
int hand = 0, tail = 0; int hand = 0, tail = 0;
unsigned mru[N_MRU]; unsigned mru[N_MRU];
memset(&mru[0], 0, sizeof(mru)); memset(&mru[0], 0, sizeof(mru));
assert(N_MRU<=256); assert(N_MRU <= 256);
f->n_mru = (MRUFLT==f_call || MRUFLT==f_jmp1 || MRUFLT==f_jcc2) ? f->n_mru = (MRUFLT == f_call || MRUFLT == f_jmp1 || MRUFLT == f_jcc2) ? N_MRU : 0;
N_MRU : 0; #endif //}
#endif //}
// FIXME: We must fit into 8 MiB because we steal one bit. // FIXME: We must fit into 8 MiB because we steal one bit.
// find a 16 MiB large empty address space // find a 16 MiB large empty address space
{ {
int which; int which;
unsigned char buf[256]; unsigned char buf[256];
memset(buf,0,256); memset(buf, 0, 256);
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++)
if (CONDF(which,b,ic,lastcall) && get_le32(b+ic+1)+ic+1 >= size) if (CONDF(which, b, ic, lastcall) && get_le32(b + ic + 1) + ic + 1 >= size) {
{ buf[b[ic + 1]] |= 1;
buf[b[ic+1]] |= 1;
} }
UNUSED(which); UNUSED(which);
@ -142,37 +121,33 @@ static int F(Filter *f)
} }
const unsigned char cto8 = f->cto; const unsigned char cto8 = f->cto;
#ifdef U #ifdef U
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
#endif #endif
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++) {
{
int which; int which;
int f_on = 0; int f_on = 0;
if (!CONDF(which,b,ic,lastcall)) if (!CONDF(which, b, ic, lastcall))
continue; continue;
++wtally[which]; ++wtally[which];
jc = get_le32(b+ic+1)+ic+1; jc = get_le32(b + ic + 1) + ic + 1;
// try to detect 'real' calls only // try to detect 'real' calls only
if (jc < size) if (jc < size) {
{
#ifdef U #ifdef U
if (2==which && NOFILT!=f_jcc2) { // 6-byte Jcc <disp32> if (2 == which && NOFILT != f_jcc2) { // 6-byte Jcc <disp32>
// Prefix 0x0f is constant, but opcode condition 0x80..0x8f // Prefix 0x0f is constant, but opcode condition 0x80..0x8f
// varies. Because we store the destination (or its mru index) // varies. Because we store the destination (or its mru index)
// in be32 big endian format, the low-addressed bytes // in be32 big endian format, the low-addressed bytes
// will tend to be constant. Swap prefix and opcode // will tend to be constant. Swap prefix and opcode
// so that constants are together for better compression. // so that constants are together for better compression.
unsigned char const t = unsigned char const t = b[ic - 1];
b[ic-1]; b[ic - 1] = b[ic];
b[ic-1] = b[ic]; b[ic] = t;
b[ic] = t;
} }
// FIXME [?]: Extend to 8 bytes if "ADD ESP, byte 4*n" follows CALL. // FIXME [?]: Extend to 8 bytes if "ADD ESP, byte 4*n" follows CALL.
// This will require two related cto's (consecutive, or otherwise). // This will require two related cto's (consecutive, or otherwise).
if ((0==which && MRUFLT==f_call) if ((0 == which && MRUFLT == f_call) || (1 == which && MRUFLT == f_jmp1) ||
|| (1==which && MRUFLT==f_jmp1) (2 == which && MRUFLT == f_jcc2)) {
|| (2==which && MRUFLT==f_jcc2) ) {
f_on = 1; f_on = 1;
// Recode the destination: narrower mru indices // Recode the destination: narrower mru indices
// should compress better than wider addresses. // should compress better than wider addresses.
@ -184,62 +159,55 @@ static int F(Filter *f)
kh -= N_MRU; kh -= N_MRU;
} }
if (mru[kh] == jc) { // destination was seen recently if (mru[kh] == jc) { // destination was seen recently
set_be32(b+ic+1,((k<<1)|0)+cto); set_be32(b + ic + 1, ((k << 1) | 0) + cto);
update_mru(jc, kh, mru, hand, tail); update_mru(jc, kh, mru, hand, tail);
break; break;
} }
} }
if (k == N_MRU) { // loop failed; jc is not in mru[] if (k == N_MRU) { // loop failed; jc is not in mru[]
set_be32(b+ic+1,((jc<<1)|1)+cto); set_be32(b + ic + 1, ((jc << 1) | 1) + cto);
// Adaptively remember recent destinations. // Adaptively remember recent destinations.
if (0 > --hand) { if (0 > --hand) {
hand = N_MRU -1; hand = N_MRU - 1;
} }
mru[hand] = jc; mru[hand] = jc;
} }
} else } else if ((0 == which && NOFILT != f_call) || (1 == which && NOFILT != f_jmp1) ||
if ((0==which && NOFILT!=f_call) (2 == which && NOFILT != f_jcc2)) {
|| (1==which && NOFILT!=f_jmp1)
|| (2==which && NOFILT!=f_jcc2) ) {
f_on = 1; f_on = 1;
set_be32(b+ic+1, jc+cto); set_be32(b + ic + 1, jc + cto);
} }
#endif #endif
if (f_on) { if (f_on) {
if (ic - lastnoncall < 5) if (ic - lastnoncall < 5) {
{ // check the last 4 bytes before this call
// check the last 4 bytes before this call for (kc = 4; kc; kc--)
for (kc = 4; kc; kc--) if (CONDF(which, b, ic - kc, lastcall) && b[ic - kc + 1] == cto8)
if (CONDF(which,b,ic-kc,lastcall) && b[ic-kc+1] == cto8) break;
break; if (kc) {
if (kc) #ifdef U
{ // restore original
#ifdef U if (2 == which) {
// restore original // Unswap prefix and opcode for 6-byte Jcc <disp32>
if (2==which) { unsigned char const t = b[ic - 1];
// Unswap prefix and opcode for 6-byte Jcc <disp32> b[ic - 1] = b[ic];
unsigned char const t = b[ic] = t;
b[ic-1];
b[ic-1] = b[ic];
b[ic] = t;
}
set_le32(b+ic+1,jc-ic-1);
#endif
if (b[ic+1] == cto8)
return 1; // fail - buffer not restored
lastnoncall = ic;
noncalls2++;
continue;
} }
set_le32(b + ic + 1, jc - ic - 1);
#endif
if (b[ic + 1] == cto8)
return 1; // fail - buffer not restored
lastnoncall = ic;
noncalls2++;
continue;
} }
calls++; }
ic += 4; calls++;
lastcall = ic+1; ic += 4;
lastcall = ic + 1;
} }
} } else {
else assert(b[ic + 1] != cto8); // this should not happen
{
assert(b[ic+1] != cto8); // this should not happen
lastnoncall = ic; lastnoncall = ic;
noncalls++; noncalls++;
} }
@ -258,19 +226,17 @@ static int F(Filter *f)
return 0; return 0;
} }
/************************************************************************* /*************************************************************************
// unfilter // unfilter
**************************************************************************/ **************************************************************************/
#ifdef U #ifdef U
static int U(Filter *f) static int U(Filter *f) {
{
unsigned ic, jc; unsigned ic, jc;
byte *const b = f->buf; byte *const b = f->buf;
const unsigned size5 = f->buf_len - 5; const unsigned size5 = f->buf_len - 5;
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
unsigned lastcall = 0; unsigned lastcall = 0;
int hand = 0, tail = 0; int hand = 0, tail = 0;
const unsigned f_call = f80_call(f); const unsigned f_call = f80_call(f);
@ -282,58 +248,50 @@ static int U(Filter *f)
for (ic = 0; ic < size5; ic++) { for (ic = 0; ic < size5; ic++) {
int which; int which;
if (CONDU(which,b,ic,lastcall)) if (CONDU(which, b, ic, lastcall)) {
{
unsigned f_on = 0; unsigned f_on = 0;
jc = get_be32(b+ic+1) - cto; jc = get_be32(b + ic + 1) - cto;
if (b[ic+1] == f->cto) if (b[ic + 1] == f->cto) {
{ if ((0 == which && MRUFLT == f_call) || (1 == which && MRUFLT == f_jmp1) ||
if ((0==which && MRUFLT==f_call) (2 == which && MRUFLT == f_jcc2)) {
|| (1==which && MRUFLT==f_jmp1)
|| (2==which && MRUFLT==f_jcc2) ) {
f_on = 1; f_on = 1;
if (1&jc) { // 1st time at this destination if (1 & jc) { // 1st time at this destination
jc >>= 1; jc >>= 1;
if (0 > --hand) { if (0 > --hand) {
hand = N_MRU -1; hand = N_MRU - 1;
}
mru[hand] = jc;
} }
else { // not 1st time at this destination mru[hand] = jc;
jc >>= 1; } else { // not 1st time at this destination
if (N_MRU <= jc) { jc >>= 1;
throwCompressedDataViolation(); if (N_MRU <= jc) {
} throwCompressedDataViolation();
int kh = jc + hand;
if (N_MRU <= kh) {
kh -= N_MRU;
}
jc = mru[kh];
update_mru(jc, kh, mru, hand, tail);
} }
set_le32(b+ic+1,jc-ic-1); int kh = jc + hand;
} else if (N_MRU <= kh) {
if ((0==which && NOFILT!=f_call) kh -= N_MRU;
|| (1==which && NOFILT!=f_jmp1) }
|| (2==which && NOFILT!=f_jcc2) ) { jc = mru[kh];
update_mru(jc, kh, mru, hand, tail);
}
set_le32(b + ic + 1, jc - ic - 1);
} else if ((0 == which && NOFILT != f_call) || (1 == which && NOFILT != f_jmp1) ||
(2 == which && NOFILT != f_jcc2)) {
f_on = 1; f_on = 1;
set_le32(b+ic+1,jc-ic-1); set_le32(b + ic + 1, jc - ic - 1);
} }
if (2==which && NOFILT!=f_jcc2) { if (2 == which && NOFILT != f_jcc2) {
// Unswap prefix and opcode for 6-byte Jcc <disp32> // Unswap prefix and opcode for 6-byte Jcc <disp32>
unsigned char const t = unsigned char const t = b[ic - 1];
b[ic-1]; b[ic - 1] = b[ic];
b[ic-1] = b[ic]; b[ic] = t;
b[ic] = t;
} }
if (f_on) { if (f_on) {
f->calls++; f->calls++;
ic += 4; ic += 4;
f->lastcall = lastcall = ic+1; f->lastcall = lastcall = ic + 1;
} }
} } else
else
f->noncalls++; f->noncalls++;
} }
} }

View File

@ -29,14 +29,11 @@
<jreiser@users.sourceforge.net> <jreiser@users.sourceforge.net>
*/ */
/************************************************************************* /*************************************************************************
// filter / scan // filter / scan
**************************************************************************/ **************************************************************************/
static int F(Filter *f) static int F(Filter *f) {
{
#ifdef U #ifdef U
// filter // filter
byte *b = f->buf; byte *b = f->buf;
@ -55,20 +52,17 @@ static int F(Filter *f)
// find a 16 MiB large empty address space // find a 16 MiB large empty address space
{ {
unsigned char buf[256]; unsigned char buf[256];
memset(buf,0,256); memset(buf, 0, 256);
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++) {
{ if (!COND(b, ic, lastcall, id))
if (!COND(b,ic,lastcall,id))
continue; continue;
jc = get_le32(b+ic+1)+ic+1; jc = get_le32(b + ic + 1) + ic + 1;
if (jc < size) if (jc < size) {
{
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8 if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
return -1; return -1;
} } else
else buf[b[ic + 1]] |= 1;
buf[b[ic+1]] |= 1;
} }
if (getcto(f, buf) < 0) if (getcto(f, buf) < 0)
@ -76,35 +70,31 @@ static int F(Filter *f)
} }
const unsigned char cto8 = f->cto; const unsigned char cto8 = f->cto;
#ifdef U #ifdef U
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
#endif #endif
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++) {
{ if (!COND(b, ic, lastcall, id))
if (!COND(b,ic,lastcall,id))
continue; continue;
jc = get_le32(b+ic+1)+ic+1; jc = get_le32(b + ic + 1) + ic + 1;
// try to detect 'real' calls only // try to detect 'real' calls only
if (jc < size) if (jc < size) {
{
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8 assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
#ifdef U #ifdef U
set_be32(b+ic+1,jc+addvalue+cto); set_be32(b + ic + 1, jc + addvalue + cto);
#endif #endif
if (ic - lastnoncall < 5) if (ic - lastnoncall < 5) {
{
// check the last 4 bytes before this call // check the last 4 bytes before this call
for (kc = 4; kc; kc--) for (kc = 4; kc; kc--)
if (COND(b,ic-kc,lastcall,id) && b[ic-kc+1] == cto8) if (COND(b, ic - kc, lastcall, id) && b[ic - kc + 1] == cto8)
break; break;
if (kc) if (kc) {
{
#ifdef U #ifdef U
// restore original // restore original
set_le32(b+ic+1,jc-ic-1); set_le32(b + ic + 1, jc - ic - 1);
#endif #endif
if (b[ic+1] == cto8) if (b[ic + 1] == cto8)
return 1; // fail - buffer not restored return 1; // fail - buffer not restored
lastnoncall = ic; lastnoncall = ic;
noncalls2++; noncalls2++;
continue; continue;
@ -112,11 +102,9 @@ static int F(Filter *f)
} }
calls++; calls++;
ic += 4; ic += 4;
lastcall = ic+1; lastcall = ic + 1;
} } else {
else assert(b[ic + 1] != cto8); // this should not happen
{
assert(b[ic+1] != cto8); // this should not happen
lastnoncall = ic; lastnoncall = ic;
noncalls++; noncalls++;
} }
@ -133,42 +121,36 @@ static int F(Filter *f)
return 0; return 0;
} }
/************************************************************************* /*************************************************************************
// unfilter // unfilter
**************************************************************************/ **************************************************************************/
#ifdef U #ifdef U
static int U(Filter *f) static int U(Filter *f) {
{
byte *b = f->buf; byte *b = f->buf;
const unsigned size5 = f->buf_len - 5; const unsigned size5 = f->buf_len - 5;
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
const unsigned id = f->id; const unsigned id = f->id;
unsigned lastcall = 0; unsigned lastcall = 0;
unsigned ic, jc; unsigned ic, jc;
for (ic = 0; ic < size5; ic++) for (ic = 0; ic < size5; ic++)
if (COND(b,ic,lastcall,id)) if (COND(b, ic, lastcall, id)) {
{ jc = get_be32(b + ic + 1);
jc = get_be32(b+ic+1); if (b[ic + 1] == f->cto) {
if (b[ic+1] == f->cto) set_le32(b + ic + 1, jc - ic - 1 - addvalue - cto);
{
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
f->calls++; f->calls++;
ic += 4; ic += 4;
f->lastcall = lastcall = ic+1; f->lastcall = lastcall = ic + 1;
} } else
else
f->noncalls++; f->noncalls++;
} }
return 0; return 0;
} }
#endif #endif
#undef F #undef F
#undef U #undef U

View File

@ -25,145 +25,118 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// 16-bit call-/swaptrick ("naive") // 16-bit call-/swaptrick ("naive")
**************************************************************************/ **************************************************************************/
#define CTSW16(f, cond1, cond2, addvalue, get, set) \ #define CTSW16(f, cond1, cond2, addvalue, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 3; \ byte *b_end = b + f->buf_len - 3; \
do { \ do { \
if (cond1) \ if (cond1) { \
{ \ b += 1; \
b += 1; \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b) + (addvalue)); \
set(b, get(b) + (addvalue)); \ f->calls++; \
f->calls++; \ b += 2 - 1; \
b += 2 - 1; \ } else if (cond2) { \
} \ b += 1; \
else if (cond2) \ unsigned a = (unsigned) (b - f->buf); \
{ \ f->lastcall = a; \
b += 1; \ set(b, get(b)); \
unsigned a = (unsigned) (b - f->buf); \ f->calls++; \
f->lastcall = a; \ b += 2 - 1; \
set(b, get(b)); \ } \
f->calls++; \ } while (++b < b_end); \
b += 2 - 1; \ if (f->lastcall) \
} \ f->lastcall += 2; \
} while (++b < b_end); \
if (f->lastcall) f->lastcall += 2; \
return 0; return 0;
// filter // filter
static int f_ctsw16_e8_e9(Filter *f) static int f_ctsw16_e8_e9(Filter *f) {
{
CTSW16(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le16, set_be16) CTSW16(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le16, set_be16)
} }
static int f_ctsw16_e9_e8(Filter *f) static int f_ctsw16_e9_e8(Filter *f) {
{
CTSW16(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le16, set_be16) CTSW16(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le16, set_be16)
} }
// unfilter // unfilter
static int u_ctsw16_e8_e9(Filter *f) static int u_ctsw16_e8_e9(Filter *f) {
{
CTSW16(f, (*b == 0xe8), (*b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16) CTSW16(f, (*b == 0xe8), (*b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16)
} }
static int u_ctsw16_e9_e8(Filter *f) static int u_ctsw16_e9_e8(Filter *f) {
{
CTSW16(f, (*b == 0xe9), (*b == 0xe8), 0 - a - f->addvalue, get_be16, set_le16) CTSW16(f, (*b == 0xe9), (*b == 0xe8), 0 - a - f->addvalue, get_be16, set_le16)
} }
// scan // scan
static int s_ctsw16_e8_e9(Filter *f) static int s_ctsw16_e8_e9(Filter *f) {
{
CTSW16(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le16, set_dummy) CTSW16(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le16, set_dummy)
} }
static int s_ctsw16_e9_e8(Filter *f) static int s_ctsw16_e9_e8(Filter *f) {
{
CTSW16(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le16, set_dummy) CTSW16(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le16, set_dummy)
} }
#undef CTSW16 #undef CTSW16
/************************************************************************* /*************************************************************************
// 32-bit call-/swaptrick ("naive") // 32-bit call-/swaptrick ("naive")
**************************************************************************/ **************************************************************************/
#define CTSW32(f, cond1, cond2, addvalue, get, set) \ #define CTSW32(f, cond1, cond2, addvalue, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 5; \ byte *b_end = b + f->buf_len - 5; \
do { \ do { \
if (cond1) \ if (cond1) { \
{ \ b += 1; \
b += 1; \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b) + (addvalue)); \
set(b, get(b) + (addvalue)); \ f->calls++; \
f->calls++; \ b += 4 - 1; \
b += 4 - 1; \ } else if (cond2) { \
} \ b += 1; \
else if (cond2) \ unsigned a = (unsigned) (b - f->buf); \
{ \ f->lastcall = a; \
b += 1; \ set(b, get(b)); \
unsigned a = (unsigned) (b - f->buf); \ f->calls++; \
f->lastcall = a; \ b += 4 - 1; \
set(b, get(b)); \ } \
f->calls++; \ } while (++b < b_end); \
b += 4 - 1; \ if (f->lastcall) \
} \ f->lastcall += 4; \
} while (++b < b_end); \
if (f->lastcall) f->lastcall += 4; \
return 0; return 0;
// filter // filter
static int f_ctsw32_e8_e9(Filter *f) static int f_ctsw32_e8_e9(Filter *f) {
{
CTSW32(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le32, set_be32) CTSW32(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le32, set_be32)
} }
static int f_ctsw32_e9_e8(Filter *f) static int f_ctsw32_e9_e8(Filter *f) {
{
CTSW32(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le32, set_be32) CTSW32(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le32, set_be32)
} }
// unfilter // unfilter
static int u_ctsw32_e8_e9(Filter *f) static int u_ctsw32_e8_e9(Filter *f) {
{
CTSW32(f, (*b == 0xe8), (*b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32) CTSW32(f, (*b == 0xe8), (*b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32)
} }
static int u_ctsw32_e9_e8(Filter *f) static int u_ctsw32_e9_e8(Filter *f) {
{
CTSW32(f, (*b == 0xe9), (*b == 0xe8), 0 - a - f->addvalue, get_be32, set_le32) CTSW32(f, (*b == 0xe9), (*b == 0xe8), 0 - a - f->addvalue, get_be32, set_le32)
} }
// scan // scan
static int s_ctsw32_e8_e9(Filter *f) static int s_ctsw32_e8_e9(Filter *f) {
{
CTSW32(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le32, set_dummy) CTSW32(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le32, set_dummy)
} }
static int s_ctsw32_e9_e8(Filter *f) static int s_ctsw32_e9_e8(Filter *f) {
{
CTSW32(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le32, set_dummy) CTSW32(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le32, set_dummy)
} }
#undef CTSW32 #undef CTSW32
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */

View File

@ -25,21 +25,14 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "../conf.h" #include "../conf.h"
#include "../filter.h" #include "../filter.h"
static unsigned static unsigned umin(const unsigned a, const unsigned b) { return (a <= b) ? a : b; }
umin(const unsigned a, const unsigned b)
{
return (a<=b) ? a : b;
}
#define set_dummy(p, v) ((void)0)
#define get_8(p) (*(p))
#define set_8(p, v) (*(p) = (v))
#define set_dummy(p, v) ((void) 0)
#define get_8(p) (*(p))
#define set_8(p, v) (*(p) = (v))
/************************************************************************* /*************************************************************************
// util // util
@ -47,7 +40,6 @@ umin(const unsigned a, const unsigned b)
#include "getcto.h" #include "getcto.h"
/************************************************************************* /*************************************************************************
// simple filters: calltrick / swaptrick / delta / ... // simple filters: calltrick / swaptrick / delta / ...
**************************************************************************/ **************************************************************************/
@ -60,86 +52,80 @@ umin(const unsigned a, const unsigned b)
#include "sub16.h" #include "sub16.h"
#include "sub32.h" #include "sub32.h"
/************************************************************************* /*************************************************************************
// cto calltrick // cto calltrick
**************************************************************************/ **************************************************************************/
#define COND(b,x) (b[x] == 0xe8) #define COND(b, x) (b[x] == 0xe8)
#define F f_cto32_e8_bswap_le #define F f_cto32_e8_bswap_le
#define U u_cto32_e8_bswap_le #define U u_cto32_e8_bswap_le
#include "cto.h" #include "cto.h"
#define F s_cto32_e8_bswap_le #define F s_cto32_e8_bswap_le
#include "cto.h" #include "cto.h"
#undef COND #undef COND
#define COND(b,x) (b[x] == 0xe9) #define COND(b, x) (b[x] == 0xe9)
#define F f_cto32_e9_bswap_le #define F f_cto32_e9_bswap_le
#define U u_cto32_e9_bswap_le #define U u_cto32_e9_bswap_le
#include "cto.h" #include "cto.h"
#define F s_cto32_e9_bswap_le #define F s_cto32_e9_bswap_le
#include "cto.h" #include "cto.h"
#undef COND #undef COND
#define COND(b,x) (b[x] == 0xe8 || b[x] == 0xe9) #define COND(b, x) (b[x] == 0xe8 || b[x] == 0xe9)
#define F f_cto32_e8e9_bswap_le #define F f_cto32_e8e9_bswap_le
#define U u_cto32_e8e9_bswap_le #define U u_cto32_e8e9_bswap_le
#include "cto.h" #include "cto.h"
#define F s_cto32_e8e9_bswap_le #define F s_cto32_e8e9_bswap_le
#include "cto.h" #include "cto.h"
#undef COND #undef COND
/************************************************************************* /*************************************************************************
// cto calltrick with jmp // cto calltrick with jmp
**************************************************************************/ **************************************************************************/
#define COND(b,x,lastcall) (b[x] == 0xe8 || b[x] == 0xe9) #define COND(b, x, lastcall) (b[x] == 0xe8 || b[x] == 0xe9)
#define F f_ctoj32_e8e9_bswap_le #define F f_ctoj32_e8e9_bswap_le
#define U u_ctoj32_e8e9_bswap_le #define U u_ctoj32_e8e9_bswap_le
#include "ctoj.h" #include "ctoj.h"
#define F s_ctoj32_e8e9_bswap_le #define F s_ctoj32_e8e9_bswap_le
#include "ctoj.h" #include "ctoj.h"
#undef COND #undef COND
/************************************************************************* /*************************************************************************
// cto calltrick with jmp, optional jcc // cto calltrick with jmp, optional jcc
**************************************************************************/ **************************************************************************/
#define COND1(b,x) (b[x] == 0xe8 || b[x] == 0xe9) #define COND1(b, x) (b[x] == 0xe8 || b[x] == 0xe9)
#define COND2(b,x,lc) (lc!=(x) && 0xf==b[(x)-1] && 0x80<=b[x] && b[x]<=0x8f) #define COND2(b, x, lc) (lc != (x) && 0xf == b[(x) -1] && 0x80 <= b[x] && b[x] <= 0x8f)
#define COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc))) #define COND(b, x, lc, id) (COND1(b, x) || ((9 <= (0xf & (id))) && COND2(b, x, lc)))
#define F f_ctok32_e8e9_bswap_le #define F f_ctok32_e8e9_bswap_le
#define U u_ctok32_e8e9_bswap_le #define U u_ctok32_e8e9_bswap_le
#include "ctok.h" #include "ctok.h"
#define F s_ctok32_e8e9_bswap_le #define F s_ctok32_e8e9_bswap_le
#include "ctok.h" #include "ctok.h"
#undef COND #undef COND
#undef COND2 #undef COND2
#undef COND1 #undef COND1
/************************************************************************* /*************************************************************************
// cto calltrick with jmp and jcc and relative renumbering // cto calltrick with jmp and jcc and relative renumbering
**************************************************************************/ **************************************************************************/
#define COND_CALL(which,b,x) ((which = 0), b[x] == 0xe8) #define COND_CALL(which, b, x) ((which = 0), b[x] == 0xe8)
#define COND_JMP( which,b,x) ((which = 1), b[x] == 0xe9) #define COND_JMP(which, b, x) ((which = 1), b[x] == 0xe9)
#define COND_JCC( which,b,lastcall,x,y,z) ((which = 2), \ #define COND_JCC(which, b, lastcall, x, y, z) \
(lastcall!=(x) && 0xf==b[y] && 0x80<=b[z] && b[z]<=0x8f)) ((which = 2), (lastcall != (x) && 0xf == b[y] && 0x80 <= b[z] && b[z] <= 0x8f))
#define COND1(which,b,x) (COND_CALL(which,b,x) || COND_JMP(which,b,x)) #define COND1(which, b, x) (COND_CALL(which, b, x) || COND_JMP(which, b, x))
#define COND2(which,b,lastcall,x,y,z) COND_JCC(which,b,lastcall,x,y,z) #define COND2(which, b, lastcall, x, y, z) COND_JCC(which, b, lastcall, x, y, z)
#define CONDF(which,b,x,lastcall) \ #define CONDF(which, b, x, lastcall) (COND1(which, b, x) || COND2(which, b, lastcall, x, (x) -1, x))
(COND1(which,b,x) || COND2(which,b,lastcall,x,(x)-1, x )) #define CONDU(which, b, x, lastcall) (COND1(which, b, x) || COND2(which, b, lastcall, x, x, (x) -1))
#define CONDU(which,b,x,lastcall) \
(COND1(which,b,x) || COND2(which,b,lastcall,x, x ,(x)-1))
#define F f_ctojr32_e8e9_bswap_le #define F f_ctojr32_e8e9_bswap_le
#define U u_ctojr32_e8e9_bswap_le #define U u_ctojr32_e8e9_bswap_le
#include "ctojr.h" #include "ctojr.h"
#define F s_ctojr32_e8e9_bswap_le #define F s_ctojr32_e8e9_bswap_le
#include "ctojr.h" #include "ctojr.h"
#undef CONDU #undef CONDU
@ -150,24 +136,23 @@ umin(const unsigned a, const unsigned b)
#undef COND_JMP #undef COND_JMP
#undef COND_CALL #undef COND_CALL
/************************************************************************* /*************************************************************************
// PowerPC branch [incl. call] trick // PowerPC branch [incl. call] trick
**************************************************************************/ **************************************************************************/
#define COND(b,x) (18==(get_be32(b+x)>>26)) #define COND(b, x) (18 == (get_be32(b + x) >> 26))
#define F f_ppcbxx #define F f_ppcbxx
#define U u_ppcbxx #define U u_ppcbxx
#include "ppcbxx.h" #include "ppcbxx.h"
#define F s_ppcbxx #define F s_ppcbxx
#include "ppcbxx.h" #include "ppcbxx.h"
#undef COND #undef COND
/************************************************************************* /*************************************************************************
// database for use in class Filter // database for use in class Filter
**************************************************************************/ **************************************************************************/
// clang-format off
/*static*/ const FilterImpl::FilterEntry FilterImpl::filters[] = { /*static*/ const FilterImpl::FilterEntry FilterImpl::filters[] = {
// no filter // no filter
{ 0x00, 0, 0, nullptr, nullptr, nullptr }, { 0x00, 0, 0, nullptr, nullptr, nullptr },
@ -265,6 +250,7 @@ umin(const unsigned a, const unsigned b)
// PowerPC branch+call trick // PowerPC branch+call trick
{ 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx }, { 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx },
}; };
// clang-format on
/*static*/ const int FilterImpl::n_filters = TABLESIZE(filters); /*static*/ const int FilterImpl::n_filters = TABLESIZE(filters);

View File

@ -25,22 +25,16 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
static int getcto(Filter *f, const byte *buf, const int n=256) static int getcto(Filter *f, const byte *buf, const int n = 256) {
{
int ic = n; int ic = n;
if (f->preferred_ctos) if (f->preferred_ctos) {
{ for (const int *pc = f->preferred_ctos; *pc >= 0; pc++) {
for (const int *pc = f->preferred_ctos; *pc >= 0; pc++) if (*pc < n && buf[*pc] == 0) {
{
if (*pc < n && buf[*pc] == 0)
{
ic = *pc; ic = *pc;
break; break;
} }
@ -60,7 +54,7 @@ static int getcto(Filter *f, const byte *buf, const int n=256)
break; break;
if (ic >= n) if (ic >= n)
//throwCantPack("call trick problem"); // throwCantPack("call trick problem");
return -1; return -1;
f->cto = (byte) ic; f->cto = (byte) ic;

View File

@ -29,16 +29,13 @@
<jreiser@users.sourceforge.net> <jreiser@users.sourceforge.net>
*/ */
/************************************************************************* /*************************************************************************
// filter / scan // filter / scan
**************************************************************************/ **************************************************************************/
#define W_CTO 4 /* width of cto; must match stub/ppc_bxx.S */ #define W_CTO 4 /* width of cto; must match stub/ppc_bxx.S */
static int F(Filter *f) static int F(Filter *f) {
{
#ifdef U #ifdef U
// filter // filter
byte *b = f->buf; byte *b = f->buf;
@ -47,8 +44,8 @@ static int F(Filter *f)
// scan // scan
const byte *b = f->buf; const byte *b = f->buf;
#endif #endif
const unsigned size = umin(f->buf_len, 0u - (~0u<<(32 - (6+ W_CTO)))); const unsigned size = umin(f->buf_len, 0u - (~0u << (32 - (6 + W_CTO))));
const unsigned size4 = size -4; const unsigned size4 = size - 4;
unsigned ic; unsigned ic;
unsigned calls = 0, noncalls = 0; unsigned calls = 0, noncalls = 0;
@ -58,18 +55,19 @@ static int F(Filter *f)
{ {
unsigned char buf[256]; unsigned char buf[256];
unsigned short wbuf[256]; unsigned short wbuf[256];
const size_t WW = (size_t)0 - ((~(size_t)0) << W_CTO); // ??? const size_t WW = (size_t) 0 - ((~(size_t) 0) << W_CTO); // ???
memset(wbuf, 0, sizeof(wbuf)); memset(wbuf, 0, sizeof(wbuf));
memset(buf , 0, WW); memset(buf, 0, WW);
memset(buf + WW, 1, 256 - WW); memset(buf + WW, 1, 256 - WW);
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) { for (ic = 0; ic <= size4; ic += 4)
unsigned const off = (int)(get_be32(b+ic)<<6) >>6; if (COND(b, ic)) {
if (size <= (off & (~0u<<2))+ic) { unsigned const off = (int) (get_be32(b + ic) << 6) >> 6;
buf[(~(~0u<<W_CTO)) & (off>>(26 - W_CTO))] |= 1; if (size <= (off & (~0u << 2)) + ic) {
++wbuf[0xff&(off>>18)]; buf[(~(~0u << W_CTO)) & (off >> (26 - W_CTO))] |= 1;
++wbuf[0xff & (off >> 18)];
}
} }
}
if (getcto(f, buf) < 0) { if (getcto(f, buf) < 0) {
#if (W_CTO != 0) #if (W_CTO != 0)
@ -81,29 +79,30 @@ static int F(Filter *f)
} }
const unsigned char cto8 = f->cto; const unsigned char cto8 = f->cto;
#ifdef U #ifdef U
const unsigned cto = (unsigned)f->cto << (24+2 - W_CTO); const unsigned cto = (unsigned) f->cto << (24 + 2 - W_CTO);
#endif #endif
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) { for (ic = 0; ic <= size4; ic += 4)
unsigned const word = get_be32(b+ic); if (COND(b, ic)) {
unsigned const off = (int)(word<<6) >>6; unsigned const word = get_be32(b + ic);
unsigned const jc = (off & (~0u<<2))+ic; unsigned const off = (int) (word << 6) >> 6;
// try to detect 'real' calls only unsigned const jc = (off & (~0u << 2)) + ic;
if (jc < size) { // try to detect 'real' calls only
if (jc < size) {
#ifdef U #ifdef U
set_be32(b+ic,(0xfc000003&word) | (jc+addvalue+cto)); set_be32(b + ic, (0xfc000003 & word) | (jc + addvalue + cto));
#endif #endif
calls++; calls++;
lastcall = ic; lastcall = ic;
} } else {
else {
#if (W_CTO != 0) #if (W_CTO != 0)
assert((~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) != (unsigned) cto8); // this should not happen assert((~(~0u << W_CTO) & (word >> (24 + 2 - W_CTO))) !=
(unsigned) cto8); // this should not happen
#endif #endif
lastnoncall = ic; lastnoncall = ic;
noncalls++; noncalls++;
}
} }
}
f->calls = calls; f->calls = calls;
f->noncalls = noncalls; f->noncalls = noncalls;
@ -117,37 +116,34 @@ static int F(Filter *f)
return 0; return 0;
} }
/************************************************************************* /*************************************************************************
// unfilter // unfilter
**************************************************************************/ **************************************************************************/
#ifdef U #ifdef U
static int U(Filter *f) static int U(Filter *f) {
{
byte *b = f->buf; byte *b = f->buf;
const unsigned size4 = umin(f->buf_len - 4, 0u - (~0u<<(32 - (6+ W_CTO)))); const unsigned size4 = umin(f->buf_len - 4, 0u - (~0u << (32 - (6 + W_CTO))));
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
unsigned ic; unsigned ic;
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) { for (ic = 0; ic <= size4; ic += 4)
unsigned const word = get_be32(b+ic); if (COND(b, ic)) {
if ((~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) == (unsigned) f->cto) { unsigned const word = get_be32(b + ic);
unsigned const jc = word & (~(~0u<<(26 - W_CTO)) & (~0u<<2)); if ((~(~0u << W_CTO) & (word >> (24 + 2 - W_CTO))) == (unsigned) f->cto) {
set_be32(b+ic, (0xfc000003&word)|(0x03fffffc&(jc-ic-addvalue))); unsigned const jc = word & (~(~0u << (26 - W_CTO)) & (~0u << 2));
f->calls++; set_be32(b + ic, (0xfc000003 & word) | (0x03fffffc & (jc - ic - addvalue)));
f->lastcall = ic; f->calls++;
f->lastcall = ic;
} else {
f->noncalls++;
}
} }
else {
f->noncalls++;
}
}
return 0; return 0;
} }
#endif #endif
#undef F #undef F
#undef U #undef U

View File

@ -25,58 +25,60 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
#define SUB(f, N, T, get, set) \ #define SUB(f, N, T, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
unsigned l = f->buf_len / sizeof(T); \ unsigned l = f->buf_len / sizeof(T); \
int i; \ int i; \
T d[N]; \ T d[N]; \
\ \
i = N - 1; do d[i] = 0; while (--i >= 0); \ i = N - 1; \
\ do \
i = N - 1; \ d[i] = 0; \
do { \ while (--i >= 0); \
T delta = (T) (get(b) - d[i]); \ \
set(b, delta); \ i = N - 1; \
d[i] = (T) (d[i] + delta); \ do { \
b += sizeof(T); \ T delta = (T) (get(b) - d[i]); \
if (--i < 0) \ set(b, delta); \
i = N - 1; \ d[i] = (T) (d[i] + delta); \
} while (--l > 0); \ b += sizeof(T); \
f->calls = (f->buf_len / sizeof(T)) - N; \ if (--i < 0) \
assert((int)f->calls > 0); \ i = N - 1; \
} while (--l > 0); \
f->calls = (f->buf_len / sizeof(T)) - N; \
assert((int) f->calls > 0); \
return 0; return 0;
#define ADD(f, N, T, get, set) \
#define ADD(f, N, T, get, set) \ byte *b = f->buf; \
byte *b = f->buf; \ unsigned l = f->buf_len / sizeof(T); \
unsigned l = f->buf_len / sizeof(T); \ int i; \
int i; \ T d[N]; \
T d[N]; \ \
\ i = N - 1; \
i = N - 1; do d[i] = 0; while (--i >= 0); \ do \
\ d[i] = 0; \
i = N - 1; \ while (--i >= 0); \
do { \ \
d[i] = (T) (d[i] + get(b)); \ i = N - 1; \
set(b, d[i]); \ do { \
b += sizeof(T); \ d[i] = (T) (d[i] + get(b)); \
if (--i < 0) \ set(b, d[i]); \
i = N - 1; \ b += sizeof(T); \
} while (--l > 0); \ if (--i < 0) \
f->calls = (f->buf_len / sizeof(T)) - N; \ i = N - 1; \
assert((int)f->calls > 0); \ } while (--l > 0); \
f->calls = (f->buf_len / sizeof(T)) - N; \
assert((int) f->calls > 0); \
return 0; return 0;
#define SCAN(f, N, T, get, set) \
#define SCAN(f, N, T, get, set) \ f->calls = (f->buf_len / sizeof(T)) - N; \
f->calls = (f->buf_len / sizeof(T)) - N; \ assert((int) f->calls > 0); \
assert((int)f->calls > 0); \
return 0; return 0;
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */

View File

@ -25,88 +25,46 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
#include "sub.hh" #include "sub.hh"
#define SUB16(f, N) SUB(f, N, unsigned short, get_le16, set_le16) #define SUB16(f, N) SUB(f, N, unsigned short, get_le16, set_le16)
#define ADD16(f, N) ADD(f, N, unsigned short, get_le16, set_le16) #define ADD16(f, N) ADD(f, N, unsigned short, get_le16, set_le16)
#define SCAN16(f, N) SCAN(f, N, unsigned short, get_le16, set_le16) #define SCAN16(f, N) SCAN(f, N, unsigned short, get_le16, set_le16)
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
// filter // filter
static int f_sub16_1(Filter *f) static int f_sub16_1(Filter *f) { SUB16(f, 1) }
{
SUB16(f, 1)
}
static int f_sub16_2(Filter *f) static int f_sub16_2(Filter *f) { SUB16(f, 2) }
{
SUB16(f, 2)
}
static int f_sub16_3(Filter *f) static int f_sub16_3(Filter *f) { SUB16(f, 3) }
{
SUB16(f, 3)
}
static int f_sub16_4(Filter *f)
{
SUB16(f, 4)
}
static int f_sub16_4(Filter *f) { SUB16(f, 4) }
// unfilter // unfilter
static int u_sub16_1(Filter *f) static int u_sub16_1(Filter *f) { ADD16(f, 1) }
{
ADD16(f, 1)
}
static int u_sub16_2(Filter *f) static int u_sub16_2(Filter *f) { ADD16(f, 2) }
{
ADD16(f, 2)
}
static int u_sub16_3(Filter *f) static int u_sub16_3(Filter *f) { ADD16(f, 3) }
{
ADD16(f, 3)
}
static int u_sub16_4(Filter *f)
{
ADD16(f, 4)
}
static int u_sub16_4(Filter *f) { ADD16(f, 4) }
// scan // scan
static int s_sub16_1(Filter *f) static int s_sub16_1(Filter *f) { SCAN16(f, 1) }
{
SCAN16(f, 1)
}
static int s_sub16_2(Filter *f) static int s_sub16_2(Filter *f) { SCAN16(f, 2) }
{
SCAN16(f, 2)
}
static int s_sub16_3(Filter *f) static int s_sub16_3(Filter *f) { SCAN16(f, 3) }
{
SCAN16(f, 3)
}
static int s_sub16_4(Filter *f)
{
SCAN16(f, 4)
}
static int s_sub16_4(Filter *f) { SCAN16(f, 4) }
#undef SUB #undef SUB
#undef ADD #undef ADD

View File

@ -25,88 +25,46 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
#include "sub.hh" #include "sub.hh"
#define SUB32(f, N) SUB(f, N, unsigned int, get_le32, set_le32) #define SUB32(f, N) SUB(f, N, unsigned int, get_le32, set_le32)
#define ADD32(f, N) ADD(f, N, unsigned int, get_le32, set_le32) #define ADD32(f, N) ADD(f, N, unsigned int, get_le32, set_le32)
#define SCAN32(f, N) SCAN(f, N, unsigned int, get_le32, set_le32) #define SCAN32(f, N) SCAN(f, N, unsigned int, get_le32, set_le32)
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
// filter // filter
static int f_sub32_1(Filter *f) static int f_sub32_1(Filter *f) { SUB32(f, 1) }
{
SUB32(f, 1)
}
static int f_sub32_2(Filter *f) static int f_sub32_2(Filter *f) { SUB32(f, 2) }
{
SUB32(f, 2)
}
static int f_sub32_3(Filter *f) static int f_sub32_3(Filter *f) { SUB32(f, 3) }
{
SUB32(f, 3)
}
static int f_sub32_4(Filter *f)
{
SUB32(f, 4)
}
static int f_sub32_4(Filter *f) { SUB32(f, 4) }
// unfilter // unfilter
static int u_sub32_1(Filter *f) static int u_sub32_1(Filter *f) { ADD32(f, 1) }
{
ADD32(f, 1)
}
static int u_sub32_2(Filter *f) static int u_sub32_2(Filter *f) { ADD32(f, 2) }
{
ADD32(f, 2)
}
static int u_sub32_3(Filter *f) static int u_sub32_3(Filter *f) { ADD32(f, 3) }
{
ADD32(f, 3)
}
static int u_sub32_4(Filter *f)
{
ADD32(f, 4)
}
static int u_sub32_4(Filter *f) { ADD32(f, 4) }
// scan // scan
static int s_sub32_1(Filter *f) static int s_sub32_1(Filter *f) { SCAN32(f, 1) }
{
SCAN32(f, 1)
}
static int s_sub32_2(Filter *f) static int s_sub32_2(Filter *f) { SCAN32(f, 2) }
{
SCAN32(f, 2)
}
static int s_sub32_3(Filter *f) static int s_sub32_3(Filter *f) { SCAN32(f, 3) }
{
SCAN32(f, 3)
}
static int s_sub32_4(Filter *f)
{
SCAN32(f, 4)
}
static int s_sub32_4(Filter *f) { SCAN32(f, 4) }
#undef SUB #undef SUB
#undef ADD #undef ADD

View File

@ -25,88 +25,46 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
#include "sub.hh" #include "sub.hh"
#define SUB8(f, N) SUB(f, N, unsigned char, get_8, set_8) #define SUB8(f, N) SUB(f, N, unsigned char, get_8, set_8)
#define ADD8(f, N) ADD(f, N, unsigned char, get_8, set_8) #define ADD8(f, N) ADD(f, N, unsigned char, get_8, set_8)
#define SCAN8(f, N) SCAN(f, N, unsigned char, get_8, set_8) #define SCAN8(f, N) SCAN(f, N, unsigned char, get_8, set_8)
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
// filter // filter
static int f_sub8_1(Filter *f) static int f_sub8_1(Filter *f) { SUB8(f, 1) }
{
SUB8(f, 1)
}
static int f_sub8_2(Filter *f) static int f_sub8_2(Filter *f) { SUB8(f, 2) }
{
SUB8(f, 2)
}
static int f_sub8_3(Filter *f) static int f_sub8_3(Filter *f) { SUB8(f, 3) }
{
SUB8(f, 3)
}
static int f_sub8_4(Filter *f)
{
SUB8(f, 4)
}
static int f_sub8_4(Filter *f) { SUB8(f, 4) }
// unfilter // unfilter
static int u_sub8_1(Filter *f) static int u_sub8_1(Filter *f) { ADD8(f, 1) }
{
ADD8(f, 1)
}
static int u_sub8_2(Filter *f) static int u_sub8_2(Filter *f) { ADD8(f, 2) }
{
ADD8(f, 2)
}
static int u_sub8_3(Filter *f) static int u_sub8_3(Filter *f) { ADD8(f, 3) }
{
ADD8(f, 3)
}
static int u_sub8_4(Filter *f)
{
ADD8(f, 4)
}
static int u_sub8_4(Filter *f) { ADD8(f, 4) }
// scan // scan
static int s_sub8_1(Filter *f) static int s_sub8_1(Filter *f) { SCAN8(f, 1) }
{
SCAN8(f, 1)
}
static int s_sub8_2(Filter *f) static int s_sub8_2(Filter *f) { SCAN8(f, 2) }
{
SCAN8(f, 2)
}
static int s_sub8_3(Filter *f) static int s_sub8_3(Filter *f) { SCAN8(f, 3) }
{
SCAN8(f, 3)
}
static int s_sub8_4(Filter *f)
{
SCAN8(f, 4)
}
static int s_sub8_4(Filter *f) { SCAN8(f, 4) }
#undef SUB #undef SUB
#undef ADD #undef ADD

View File

@ -25,158 +25,91 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// 16-bit swaptrick ("naive") // 16-bit swaptrick ("naive")
**************************************************************************/ **************************************************************************/
#define SW16(f, cond, get, set) \ #define SW16(f, cond, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 3; \ byte *b_end = b + f->buf_len - 3; \
do { \ do { \
if (cond) \ if (cond) { \
{ \ b += 1; \
b += 1; \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b)); \
set(b, get(b)); \ f->calls++; \
f->calls++; \ b += 2 - 1; \
b += 2 - 1; \ } \
} \ } while (++b < b_end); \
} while (++b < b_end); \ if (f->lastcall) \
if (f->lastcall) f->lastcall += 2; \ f->lastcall += 2; \
return 0; return 0;
// filter // filter
static int f_sw16_e8(Filter *f) static int f_sw16_e8(Filter *f) { SW16(f, (*b == 0xe8), get_le16, set_be16) }
{
SW16(f, (*b == 0xe8), get_le16, set_be16)
}
static int f_sw16_e9(Filter *f) static int f_sw16_e9(Filter *f) { SW16(f, (*b == 0xe9), get_le16, set_be16) }
{
SW16(f, (*b == 0xe9), get_le16, set_be16)
}
static int f_sw16_e8e9(Filter *f)
{
SW16(f, (*b == 0xe8 || *b == 0xe9), get_le16, set_be16)
}
static int f_sw16_e8e9(Filter *f) { SW16(f, (*b == 0xe8 || *b == 0xe9), get_le16, set_be16) }
// unfilter // unfilter
static int u_sw16_e8(Filter *f) static int u_sw16_e8(Filter *f) { SW16(f, (*b == 0xe8), get_be16, set_le16) }
{
SW16(f, (*b == 0xe8), get_be16, set_le16)
}
static int u_sw16_e9(Filter *f) static int u_sw16_e9(Filter *f) { SW16(f, (*b == 0xe9), get_be16, set_le16) }
{
SW16(f, (*b == 0xe9), get_be16, set_le16)
}
static int u_sw16_e8e9(Filter *f)
{
SW16(f, (*b == 0xe8 || *b == 0xe9), get_be16, set_le16)
}
static int u_sw16_e8e9(Filter *f) { SW16(f, (*b == 0xe8 || *b == 0xe9), get_be16, set_le16) }
// scan // scan
static int s_sw16_e8(Filter *f) static int s_sw16_e8(Filter *f) { SW16(f, (*b == 0xe8), get_le16, set_dummy) }
{
SW16(f, (*b == 0xe8), get_le16, set_dummy)
}
static int s_sw16_e9(Filter *f) static int s_sw16_e9(Filter *f) { SW16(f, (*b == 0xe9), get_le16, set_dummy) }
{
SW16(f, (*b == 0xe9), get_le16, set_dummy)
}
static int s_sw16_e8e9(Filter *f)
{
SW16(f, (*b == 0xe8 || *b == 0xe9), get_le16, set_dummy)
}
static int s_sw16_e8e9(Filter *f) { SW16(f, (*b == 0xe8 || *b == 0xe9), get_le16, set_dummy) }
#undef SW16 #undef SW16
/************************************************************************* /*************************************************************************
// 32-bit swaptrick ("naive") // 32-bit swaptrick ("naive")
**************************************************************************/ **************************************************************************/
#define SW32(f, cond, get, set) \ #define SW32(f, cond, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 5; \ byte *b_end = b + f->buf_len - 5; \
do { \ do { \
if (cond) \ if (cond) { \
{ \ b += 1; \
b += 1; \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b)); \
set(b, get(b)); \ f->calls++; \
f->calls++; \ b += 4 - 1; \
b += 4 - 1; \ } \
} \ } while (++b < b_end); \
} while (++b < b_end); \ if (f->lastcall) \
if (f->lastcall) f->lastcall += 4; \ f->lastcall += 4; \
return 0; return 0;
// filter // filter
static int f_sw32_e8(Filter *f) static int f_sw32_e8(Filter *f) { SW32(f, (*b == 0xe8), get_le32, set_be32) }
{
SW32(f, (*b == 0xe8), get_le32, set_be32)
}
static int f_sw32_e9(Filter *f) static int f_sw32_e9(Filter *f) { SW32(f, (*b == 0xe9), get_le32, set_be32) }
{
SW32(f, (*b == 0xe9), get_le32, set_be32)
}
static int f_sw32_e8e9(Filter *f)
{
SW32(f, (*b == 0xe8 || *b == 0xe9), get_le32, set_be32)
}
static int f_sw32_e8e9(Filter *f) { SW32(f, (*b == 0xe8 || *b == 0xe9), get_le32, set_be32) }
// unfilter // unfilter
static int u_sw32_e8(Filter *f) static int u_sw32_e8(Filter *f) { SW32(f, (*b == 0xe8), get_be32, set_le32) }
{
SW32(f, (*b == 0xe8), get_be32, set_le32)
}
static int u_sw32_e9(Filter *f) static int u_sw32_e9(Filter *f) { SW32(f, (*b == 0xe9), get_be32, set_le32) }
{
SW32(f, (*b == 0xe9), get_be32, set_le32)
}
static int u_sw32_e8e9(Filter *f)
{
SW32(f, (*b == 0xe8 || *b == 0xe9), get_be32, set_le32)
}
static int u_sw32_e8e9(Filter *f) { SW32(f, (*b == 0xe8 || *b == 0xe9), get_be32, set_le32) }
// scan // scan
static int s_sw32_e8(Filter *f) static int s_sw32_e8(Filter *f) { SW32(f, (*b == 0xe8), get_le32, set_dummy) }
{
SW32(f, (*b == 0xe8), get_le32, set_dummy)
}
static int s_sw32_e9(Filter *f) static int s_sw32_e9(Filter *f) { SW32(f, (*b == 0xe9), get_le32, set_dummy) }
{
SW32(f, (*b == 0xe9), get_le32, set_dummy)
}
static int s_sw32_e8e9(Filter *f)
{
SW32(f, (*b == 0xe8 || *b == 0xe9), get_le32, set_dummy)
}
static int s_sw32_e8e9(Filter *f) { SW32(f, (*b == 0xe8 || *b == 0xe9), get_le32, set_dummy) }
#undef SW32 #undef SW32

View File

@ -33,67 +33,74 @@
// compression method util // compression method util
**************************************************************************/ **************************************************************************/
/*static*/ bool Packer::isValidCompressionMethod(int method) /*static*/ bool Packer::isValidCompressionMethod(int method) {
{
if (M_IS_LZMA(method)) if (M_IS_LZMA(method))
return true; return true;
return method >= M_NRV2B_LE32 && method <= M_LZMA; return method >= M_NRV2B_LE32 && method <= M_LZMA;
} }
const int *Packer::getDefaultCompressionMethods_8(int method, int level, int small) const {
#define M_LZMA_003 (M_LZMA | 0x00300)
#define M_LZMA_407 (M_LZMA | 0x40700)
static const int m_all[] = {M_NRV2B_8, M_NRV2D_8, M_NRV2E_8, M_LZMA,
M_ULTRA_BRUTE, M_LZMA_003, M_LZMA_407, M_END};
// static const int m_cl1b[] = { M_CL1B_8, M_END };
static const int m_lzma[] = {M_LZMA, M_END};
static const int m_nrv2b[] = {M_NRV2B_8, M_END};
static const int m_nrv2d[] = {M_NRV2D_8, M_END};
static const int m_nrv2e[] = {M_NRV2E_8, M_END};
const int *Packer::getDefaultCompressionMethods_8(int method, int level, int small) const if (method == M_ALL)
{ return m_all;
#define M_LZMA_003 (M_LZMA | 0x00300) // if (M_IS_CL1B(method)) return m_cl1b;
#define M_LZMA_407 (M_LZMA | 0x40700) if (M_IS_LZMA(method))
static const int m_all[] = { M_NRV2B_8, M_NRV2D_8, M_NRV2E_8, M_LZMA, M_ULTRA_BRUTE, M_LZMA_003, M_LZMA_407, M_END }; return m_lzma;
//static const int m_cl1b[] = { M_CL1B_8, M_END }; if (M_IS_NRV2B(method))
static const int m_lzma[] = { M_LZMA, M_END }; return m_nrv2b;
static const int m_nrv2b[] = { M_NRV2B_8, M_END }; if (M_IS_NRV2D(method))
static const int m_nrv2d[] = { M_NRV2D_8, M_END }; return m_nrv2d;
static const int m_nrv2e[] = { M_NRV2E_8, M_END }; if (M_IS_NRV2E(method))
return m_nrv2e;
if (method == M_ALL) return m_all;
//if (M_IS_CL1B(method)) return m_cl1b;
if (M_IS_LZMA(method)) return m_lzma;
if (M_IS_NRV2B(method)) return m_nrv2b;
if (M_IS_NRV2D(method)) return m_nrv2d;
if (M_IS_NRV2E(method)) return m_nrv2e;
if (small < 0) if (small < 0)
small = file_size <= 512*1024; small = file_size <= 512 * 1024;
if (level == 1 || small) if (level == 1 || small)
return m_nrv2b; return m_nrv2b;
return m_nrv2e; return m_nrv2e;
} }
const int *Packer::getDefaultCompressionMethods_le32(int method, int level, int small) const {
static const int m_all[] = {M_NRV2B_LE32, M_NRV2D_LE32, M_NRV2E_LE32, M_LZMA,
M_ULTRA_BRUTE, M_LZMA_003, M_LZMA_407, M_END};
// static const int m_cl1b[] = { M_CL1B_LE32, M_END };
static const int m_lzma[] = {M_LZMA, M_END};
static const int m_nrv2b[] = {M_NRV2B_LE32, M_END};
static const int m_nrv2d[] = {M_NRV2D_LE32, M_END};
static const int m_nrv2e[] = {M_NRV2E_LE32, M_END};
const int *Packer::getDefaultCompressionMethods_le32(int method, int level, int small) const if (method == M_ALL)
{ return m_all;
static const int m_all[] = { M_NRV2B_LE32, M_NRV2D_LE32, M_NRV2E_LE32, M_LZMA, M_ULTRA_BRUTE, M_LZMA_003, M_LZMA_407, M_END }; // if (M_IS_CL1B(method)) return m_cl1b;
//static const int m_cl1b[] = { M_CL1B_LE32, M_END }; if (M_IS_LZMA(method))
static const int m_lzma[] = { M_LZMA, M_END }; return m_lzma;
static const int m_nrv2b[] = { M_NRV2B_LE32, M_END }; if (M_IS_NRV2B(method))
static const int m_nrv2d[] = { M_NRV2D_LE32, M_END }; return m_nrv2b;
static const int m_nrv2e[] = { M_NRV2E_LE32, M_END }; if (M_IS_NRV2D(method))
return m_nrv2d;
if (method == M_ALL) return m_all; if (M_IS_NRV2E(method))
//if (M_IS_CL1B(method)) return m_cl1b; return m_nrv2e;
if (M_IS_LZMA(method)) return m_lzma;
if (M_IS_NRV2B(method)) return m_nrv2b;
if (M_IS_NRV2D(method)) return m_nrv2d;
if (M_IS_NRV2E(method)) return m_nrv2e;
if (small < 0) if (small < 0)
small = file_size <= 512*1024; small = file_size <= 512 * 1024;
if (level == 1 || small) if (level == 1 || small)
return m_nrv2b; return m_nrv2b;
return m_nrv2e; return m_nrv2e;
} }
/************************************************************************* /*************************************************************************
// loader util // loader util
**************************************************************************/ **************************************************************************/
static bool callsManyTimes(int format) { static bool callsManyTimes(int format) {
// clang-format off
return return
UPX_F_LINUX_ELF_i386 ==format UPX_F_LINUX_ELF_i386 ==format
|| UPX_F_LINUX_ELFI_i386 ==format || UPX_F_LINUX_ELFI_i386 ==format
@ -113,10 +120,11 @@ static bool callsManyTimes(int format) {
|| UPX_F_MACH_i386 ==format || UPX_F_MACH_i386 ==format
|| UPX_F_DYLIB_i386 ==format || UPX_F_DYLIB_i386 ==format
; ;
// clang-format on
} }
const char *Packer::getDecompressorSections() const const char *Packer::getDecompressorSections() const {
{ // clang-format off
static const char nrv2b_le32_small[] = static const char nrv2b_le32_small[] =
"N2BSMA10,N2BDEC10,N2BSMA20,N2BDEC20,N2BSMA30," "N2BSMA10,N2BDEC10,N2BSMA20,N2BDEC20,N2BSMA30,"
"N2BDEC30,N2BSMA40,N2BSMA50,N2BDEC50,N2BSMA60," "N2BDEC30,N2BSMA40,N2BSMA50,N2BDEC50,N2BSMA60,"
@ -209,6 +217,7 @@ const char *Packer::getDecompressorSections() const
"LZMA_ELF00,LZMA_DEC10,LZMA_DEC30"; "LZMA_ELF00,LZMA_DEC10,LZMA_DEC30";
static const char lzma_elf_fast[] = static const char lzma_elf_fast[] =
"LZMA_ELF00,LZMA_DEC20,LZMA_DEC30"; "LZMA_ELF00,LZMA_DEC20,LZMA_DEC30";
// clang-format on
unsigned const method = ph_forced_method(ph.method); unsigned const method = ph_forced_method(ph.method);
if (method == M_NRV2B_LE32) if (method == M_NRV2B_LE32)
@ -217,46 +226,39 @@ const char *Packer::getDecompressorSections() const
return opt->small ? nrv2d_le32_small : nrv2d_le32_fast; return opt->small ? nrv2d_le32_small : nrv2d_le32_fast;
if (method == M_NRV2E_LE32) if (method == M_NRV2E_LE32)
return opt->small ? nrv2e_le32_small : nrv2e_le32_fast; return opt->small ? nrv2e_le32_small : nrv2e_le32_fast;
// if (method == M_CL1B_LE32) // if (method == M_CL1B_LE32)
// return opt->small ? cl1b_le32_small : cl1b_le32_fast; // return opt->small ? cl1b_le32_small : cl1b_le32_fast;
if (M_IS_LZMA(method)) { if (M_IS_LZMA(method)) {
if (callsManyTimes(ph.format)) { if (callsManyTimes(ph.format)) {
return opt->small ? lzma_elf_small : lzma_elf_fast; return opt->small ? lzma_elf_small : lzma_elf_fast;
} }
return opt->small ? lzma_small : lzma_fast; return opt->small ? lzma_small : lzma_fast;
} }
throwInternalError("bad decompressor"); throwInternalError("bad decompressor");
return nullptr; return nullptr;
} }
unsigned Packer::getDecompressorWrkmemSize() const {
unsigned Packer::getDecompressorWrkmemSize() const
{
unsigned size = 0; unsigned size = 0;
if (M_IS_LZMA(ph.method)) if (M_IS_LZMA(ph.method)) {
{
const lzma_compress_result_t *res = &ph.compress_result.result_lzma; const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
// FIXME - this is for i386 only // FIXME - this is for i386 only
size = 8 + 4 + ALIGN_UP(2 * res->num_probs, 4u); size = 8 + 4 + ALIGN_UP(2 * res->num_probs, 4u);
size = ALIGN_UP(size, 16u); size = ALIGN_UP(size, 16u);
} }
assert((int)size >= 0); assert((int) size >= 0);
return size; return size;
} }
void Packer::defineDecompressorSymbols() void Packer::defineDecompressorSymbols() {
{
if (callsManyTimes(ph.format)) { if (callsManyTimes(ph.format)) {
// ELF calls the decompressor many times; the parameters change! // ELF calls the decompressor many times; the parameters change!
return; return;
} }
if (M_IS_LZMA(ph.method)) if (M_IS_LZMA(ph.method)) {
{
const lzma_compress_result_t *res = &ph.compress_result.result_lzma; const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
upx_uint32_t properties = // lc, lp, pb, dummy upx_uint32_t properties = // lc, lp, pb, dummy
(res->lit_context_bits << 0) | (res->lit_context_bits << 0) | (res->lit_pos_bits << 8) | (res->pos_bits << 16);
(res->lit_pos_bits << 8) |
(res->pos_bits << 16);
if (bele->isBE()) // big endian - bswap32 if (bele->isBE()) // big endian - bswap32
properties = bswap32(properties); properties = bswap32(properties);
@ -267,9 +269,8 @@ void Packer::defineDecompressorSymbols()
unsigned stack = getDecompressorWrkmemSize(); unsigned stack = getDecompressorWrkmemSize();
linker->defineSymbol("lzma_stack_adjust", 0u - stack); linker->defineSymbol("lzma_stack_adjust", 0u - stack);
if (ph.format == UPX_F_DOS_EXE) if (ph.format == UPX_F_DOS_EXE) {
{ linker->defineSymbol("lzma_properties_hi", properties >> 16); // pb
linker->defineSymbol("lzma_properties_hi", properties >> 16); // pb
linker->defineSymbol("lzma_c_len_hi", (ph.c_len - 2) >> 16); linker->defineSymbol("lzma_c_len_hi", (ph.c_len - 2) >> 16);
linker->defineSymbol("lzma_u_len_hi", ph.u_len >> 16); linker->defineSymbol("lzma_u_len_hi", ph.u_len >> 16);
linker->defineSymbol("lzma_u_len_segment", (ph.u_len & 0xf0000) >> 4); linker->defineSymbol("lzma_u_len_segment", (ph.u_len & 0xf0000) >> 4);

View File

@ -1,6 +1,7 @@
#define UPX_VERSION_HEX 0x040200 /* 04.02.00 */ #pragma once
#define UPX_VERSION_STRING "4.2.0" #define UPX_VERSION_HEX 0x040200 /* 04.02.00 */
#define UPX_VERSION_STRING4 "4.20" #define UPX_VERSION_STRING "4.2.0"
#define UPX_VERSION_DATE "Sep 12th 2023" #define UPX_VERSION_STRING4 "4.20"
#define UPX_VERSION_DATE_ISO "2023-09-12" #define UPX_VERSION_DATE "Oct 5th 2023"
#define UPX_VERSION_YEAR "2023" #define UPX_VERSION_DATE_ISO "2023-10-05"
#define UPX_VERSION_YEAR "2023"

View File

@ -215,7 +215,7 @@ void do_one_file(const char *const iname, char *const oname) may_throw {
if (opt->output_name) { if (opt->output_name) {
strcpy(tname, opt->output_name); strcpy(tname, opt->output_name);
if ((opt->force_overwrite || opt->force >= 2) && !preserve_link) if ((opt->force_overwrite || opt->force >= 2) && !preserve_link)
FileBase::unlink(tname, false); (void) FileBase::unlink_noexcept(tname);
} else { } else {
if (st.st_nlink < 2) if (st.st_nlink < 2)
preserve_link = false; // not needed preserve_link = false; // not needed
@ -233,7 +233,7 @@ void do_one_file(const char *const iname, char *const oname) may_throw {
preserve_link = ost.st_nlink >= 2; preserve_link = ost.st_nlink >= 2;
} else if (r == 0 && S_ISLNK(ost.st_mode)) { } else if (r == 0 && S_ISLNK(ost.st_mode)) {
// output_name is a symlink (valid or dangling) // output_name is a symlink (valid or dangling)
FileBase::unlink(tname, false); (void) FileBase::unlink_noexcept(tname);
preserve_link = false; // not needed preserve_link = false; // not needed
} else { } else {
preserve_link = false; // not needed preserve_link = false; // not needed
@ -341,7 +341,7 @@ void do_one_file(const char *const iname, char *const oname) may_throw {
static void unlink_ofile(char *oname) noexcept { static void unlink_ofile(char *oname) noexcept {
if (oname && oname[0]) { if (oname && oname[0]) {
FileBase::unlink(oname, false); (void) FileBase::unlink_noexcept(oname);
oname[0] = 0; // done with oname oname[0] = 0; // done with oname
} }
} }