src: more clang-format
This commit is contained in:
parent
632c7c4826
commit
e767461f65
2
Makefile
2
Makefile
@ -59,7 +59,7 @@ build/%/all: $$(dir $$@)debug $$(dir $$@)release ;
|
||||
include ./misc/make/Makefile-extra.mk
|
||||
|
||||
# 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
|
||||
$(MAKE) -C src $@
|
||||
endif
|
||||
|
||||
@ -80,10 +80,9 @@ endif
|
||||
# automatically format some C++ source code files
|
||||
ifeq ($(shell uname),Linux)
|
||||
# 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 += compress/compress.h filter/filter_impl.cpp
|
||||
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* [cu]*/*.[ch]*))
|
||||
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* */*.[ch]*))
|
||||
CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES))
|
||||
clang-format: PHONY $(CLANG_FORMAT_FILES)
|
||||
@echo "running upx-clang-format"
|
||||
@ -94,7 +93,7 @@ endif
|
||||
# "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)
|
||||
ifneq ($(wildcard $(top_srcdir)/.git/.),)
|
||||
CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir)
|
||||
|
||||
@ -25,8 +25,8 @@
|
||||
*/
|
||||
|
||||
#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 );
|
||||
#endif
|
||||
|
||||
|
||||
#if (WITH_LZMA)
|
||||
int upx_lzma_init(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 );
|
||||
#endif
|
||||
|
||||
|
||||
#if (WITH_NRV)
|
||||
int upx_nrv_init(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 );
|
||||
#endif
|
||||
|
||||
|
||||
#if (WITH_UCL)
|
||||
int upx_ucl_init(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);
|
||||
#endif
|
||||
|
||||
|
||||
#if (WITH_ZLIB)
|
||||
int upx_zlib_init(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);
|
||||
#endif
|
||||
|
||||
|
||||
#if (WITH_ZSTD)
|
||||
int upx_zstd_init(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 );
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
@ -765,6 +765,7 @@ void show_version(bool one_line=false);
|
||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
|
||||
unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc=0);
|
||||
|
||||
// clang-format off
|
||||
int upx_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
@ -781,6 +782,7 @@ int upx_test_overlap ( const upx_bytep buf,
|
||||
unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
// clang-format on
|
||||
|
||||
|
||||
#include "util/snprintf.h" // must get included first!
|
||||
|
||||
11
src/file.cpp
11
src/file.cpp
@ -52,18 +52,21 @@
|
||||
throwIOException("rename error", errno);
|
||||
}
|
||||
|
||||
/*static*/ bool FileBase::unlink(const char *name, bool check) {
|
||||
assert(name != nullptr && name[0] != 0);
|
||||
/*static*/ bool FileBase::unlink_noexcept(const char *name) noexcept {
|
||||
assert_noexcept(name != nullptr && name[0] != 0);
|
||||
bool success = ::unlink(name) == 0;
|
||||
#if HAVE_CHMOD
|
||||
if (!success)
|
||||
success = (::chmod(name, 0666) == 0 && ::unlink(name) == 0);
|
||||
#endif
|
||||
if (check && !success)
|
||||
throwIOException(name, errno);
|
||||
return success;
|
||||
}
|
||||
|
||||
/*static*/ void FileBase::unlink(const char *name) {
|
||||
if (!unlink_noexcept(name))
|
||||
throwIOException(name, errno);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// FileBase
|
||||
**************************************************************************/
|
||||
|
||||
@ -52,7 +52,8 @@ public:
|
||||
// static file-related util functions; will throw on error
|
||||
static void chmod(const char *name, int mode) 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:
|
||||
bool do_sopen();
|
||||
|
||||
433
src/filter/ct.h
433
src/filter/ct.h
@ -25,434 +25,325 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// 16-bit calltrick ("naive")
|
||||
**************************************************************************/
|
||||
|
||||
#define CT16(f, cond, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 3; \
|
||||
do { \
|
||||
if (cond) \
|
||||
{ \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
b += 2 - 1; \
|
||||
} \
|
||||
} while (++b < b_end); \
|
||||
if (f->lastcall) f->lastcall += 2; \
|
||||
#define CT16(f, cond, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 3; \
|
||||
do { \
|
||||
if (cond) { \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
b += 2 - 1; \
|
||||
} \
|
||||
} while (++b < b_end); \
|
||||
if (f->lastcall) \
|
||||
f->lastcall += 2; \
|
||||
return 0;
|
||||
|
||||
|
||||
|
||||
// filter: e8, e9, e8e9
|
||||
static int f_ct16_e8(Filter *f)
|
||||
{
|
||||
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_le16)
|
||||
}
|
||||
static int f_ct16_e8(Filter *f) { CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_le16) }
|
||||
|
||||
static int f_ct16_e9(Filter *f)
|
||||
{
|
||||
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_le16)
|
||||
}
|
||||
static int f_ct16_e9(Filter *f) { 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)
|
||||
}
|
||||
|
||||
|
||||
// unfilter: e8, e9, e8e9
|
||||
static int u_ct16_e8(Filter *f)
|
||||
{
|
||||
CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_le16, set_le16)
|
||||
}
|
||||
static int u_ct16_e8(Filter *f) { CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_le16, set_le16) }
|
||||
|
||||
static int u_ct16_e9(Filter *f)
|
||||
{
|
||||
CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_le16, set_le16)
|
||||
}
|
||||
static int u_ct16_e9(Filter *f) { 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)
|
||||
}
|
||||
|
||||
|
||||
// scan: e8, e9, e8e9
|
||||
static int s_ct16_e8(Filter *f)
|
||||
{
|
||||
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_dummy)
|
||||
}
|
||||
static int s_ct16_e8(Filter *f) { CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_dummy) }
|
||||
|
||||
static int s_ct16_e9(Filter *f)
|
||||
{
|
||||
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_dummy)
|
||||
}
|
||||
static int s_ct16_e9(Filter *f) { 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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
#undef CT16
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// 32-bit calltrick ("naive")
|
||||
**************************************************************************/
|
||||
|
||||
#define CT32(f, cond, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 5; \
|
||||
do { \
|
||||
if (cond) \
|
||||
{ \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
b += 4 - 1; \
|
||||
} \
|
||||
} while (++b < b_end); \
|
||||
if (f->lastcall) f->lastcall += 4; \
|
||||
#define CT32(f, cond, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 5; \
|
||||
do { \
|
||||
if (cond) { \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
b += 4 - 1; \
|
||||
} \
|
||||
} while (++b < b_end); \
|
||||
if (f->lastcall) \
|
||||
f->lastcall += 4; \
|
||||
return 0;
|
||||
|
||||
|
||||
// filter: e8, e9, e8e9
|
||||
static int f_ct32_e8(Filter *f)
|
||||
{
|
||||
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_le32)
|
||||
}
|
||||
static int f_ct32_e8(Filter *f) { CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_le32) }
|
||||
|
||||
static int f_ct32_e9(Filter *f)
|
||||
{
|
||||
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_le32)
|
||||
}
|
||||
static int f_ct32_e9(Filter *f) { 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)
|
||||
}
|
||||
|
||||
|
||||
// unfilter: e8, e9, e8e9
|
||||
static int u_ct32_e8(Filter *f)
|
||||
{
|
||||
CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_le32, set_le32)
|
||||
}
|
||||
static int u_ct32_e8(Filter *f) { CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_le32, set_le32) }
|
||||
|
||||
static int u_ct32_e9(Filter *f)
|
||||
{
|
||||
CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_le32, set_le32)
|
||||
}
|
||||
static int u_ct32_e9(Filter *f) { 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)
|
||||
}
|
||||
|
||||
|
||||
// scan: e8, e9, e8e9
|
||||
static int s_ct32_e8(Filter *f)
|
||||
{
|
||||
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_dummy)
|
||||
}
|
||||
static int s_ct32_e8(Filter *f) { CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_dummy) }
|
||||
|
||||
static int s_ct32_e9(Filter *f)
|
||||
{
|
||||
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_dummy)
|
||||
}
|
||||
static int s_ct32_e9(Filter *f) { 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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
#undef CT32
|
||||
|
||||
/*************************************************************************
|
||||
// 24-bit ARM calltrick ("naive")
|
||||
**************************************************************************/
|
||||
|
||||
#define CT24ARM_LE(f, cond, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 4; \
|
||||
do { \
|
||||
if (cond) \
|
||||
{ \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
} \
|
||||
b += 4; \
|
||||
} while (b < b_end); \
|
||||
if (f->lastcall) f->lastcall += 4; \
|
||||
#define CT24ARM_LE(f, cond, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 4; \
|
||||
do { \
|
||||
if (cond) { \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
} \
|
||||
b += 4; \
|
||||
} while (b < b_end); \
|
||||
if (f->lastcall) \
|
||||
f->lastcall += 4; \
|
||||
return 0;
|
||||
|
||||
|
||||
#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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
#undef CT24ARM_LE
|
||||
|
||||
#define CT24ARM_BE(f, cond, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 4; \
|
||||
do { \
|
||||
if (cond) \
|
||||
{ \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(1+b, get(1+b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
} \
|
||||
b += 4; \
|
||||
} while (b < b_end); \
|
||||
if (f->lastcall) f->lastcall += 4; \
|
||||
#define CT24ARM_BE(f, cond, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 4; \
|
||||
do { \
|
||||
if (cond) { \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(1 + b, get(1 + b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
} \
|
||||
b += 4; \
|
||||
} while (b < b_end); \
|
||||
if (f->lastcall) \
|
||||
f->lastcall += 4; \
|
||||
return 0;
|
||||
|
||||
#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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@ -463,89 +354,79 @@ static int s_ct24arm_be(Filter *f)
|
||||
// 26-bit ARM calltrick ("naive")
|
||||
**************************************************************************/
|
||||
|
||||
#if 1 //{ old reliable
|
||||
#define CT26ARM_LE(f, cond, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 4; \
|
||||
do { \
|
||||
if (cond) \
|
||||
{ \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
} \
|
||||
b += 4; \
|
||||
} while (b < b_end); \
|
||||
if (f->lastcall) f->lastcall += 4; \
|
||||
#if 1 //{ old reliable
|
||||
#define CT26ARM_LE(f, cond, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 4; \
|
||||
do { \
|
||||
if (cond) { \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
} \
|
||||
b += 4; \
|
||||
} while (b < b_end); \
|
||||
if (f->lastcall) \
|
||||
f->lastcall += 4; \
|
||||
return 0;
|
||||
|
||||
#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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
#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;
|
||||
do {
|
||||
unsigned const a = b - f->buf;
|
||||
int const d = dir * (f->addvalue + (a >> 2));
|
||||
unsigned const v = get_le32(f->buf); // the 32-bit instruction
|
||||
if (0x05 == (0x1f & (v >> 26))) { // b, bl
|
||||
unsigned const v = get_le32(f->buf); // the 32-bit instruction
|
||||
if (0x05 == (0x1f & (v >> 26))) { // b, bl
|
||||
f->lastcall = a;
|
||||
if (dir) set_le26(b, v + d);
|
||||
if (dir)
|
||||
set_le26(b, v + d);
|
||||
f->calls++;
|
||||
}
|
||||
else if ( (0x54 == (v >> 24) ) // b.cond
|
||||
|| (0x1a == ((v >> 25) & 0x3f)) // cb{z,nz}
|
||||
) {
|
||||
} else if ((0x54 == (v >> 24)) // b.cond
|
||||
|| (0x1a == ((v >> 25) & 0x3f)) // cb{z,nz}
|
||||
) {
|
||||
f->lastcall = a;
|
||||
if (dir) set_le19_5(b, (v >> 5) + d);
|
||||
if (dir)
|
||||
set_le19_5(b, (v >> 5) + d);
|
||||
f->calls++;
|
||||
}
|
||||
else if (0x1b == ((v >> 25) & 0x3f)) { // tb{z,nz}
|
||||
} else if (0x1b == ((v >> 25) & 0x3f)) { // tb{z,nz}
|
||||
f->lastcall = a;
|
||||
if (dir) set_le14_5(b, (v >> 5) + d);
|
||||
if (dir)
|
||||
set_le14_5(b, (v >> 5) + d);
|
||||
f->calls++;
|
||||
}
|
||||
b += 4;
|
||||
} while (b < b_end);
|
||||
if (f->lastcall) f->lastcall += 4;
|
||||
if (f->lastcall)
|
||||
f->lastcall += 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int f_CTarm64_le(Filter *f)
|
||||
{
|
||||
return CTarm64(f, 1);
|
||||
}
|
||||
static int f_CTarm64_le(Filter *f) { return CTarm64(f, 1); }
|
||||
|
||||
static int u_CTarm64_le(Filter *f)
|
||||
{
|
||||
return CTarm64(f, -1);
|
||||
}
|
||||
static int u_CTarm64_le(Filter *f) { return CTarm64(f, -1); }
|
||||
|
||||
static int s_CTarm64_le(Filter *f)
|
||||
{
|
||||
return CTarm64(f, 0);
|
||||
}
|
||||
static int s_CTarm64_le(Filter *f) { return CTarm64(f, 0); }
|
||||
|
||||
#endif //}
|
||||
#endif //}
|
||||
|
||||
#undef CT26ARM_LE
|
||||
#undef ARMCT_COND
|
||||
|
||||
@ -25,14 +25,11 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// filter / scan
|
||||
**************************************************************************/
|
||||
|
||||
static int F(Filter *f)
|
||||
{
|
||||
static int F(Filter *f) {
|
||||
#ifdef U
|
||||
// filter
|
||||
byte *b = f->buf;
|
||||
@ -50,25 +47,22 @@ static int F(Filter *f)
|
||||
// find a 16 MiB large empty address space
|
||||
{
|
||||
unsigned char buf[256];
|
||||
memset(buf,0,256);
|
||||
memset(buf, 0, 256);
|
||||
|
||||
// A call to a destination that is inside the buffer
|
||||
// will be rewritten and marked with cto8 as first byte.
|
||||
// So, a call to a destination that is outside the buffer
|
||||
// must not conflict with the mark.
|
||||
// Note that unsigned comparison checks both edges of buffer.
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
{
|
||||
if (!COND(b,ic))
|
||||
for (ic = 0; ic < size - 5; ic++) {
|
||||
if (!COND(b, ic))
|
||||
continue;
|
||||
jc = get_le32(b+ic+1)+ic+1;
|
||||
if (jc < size)
|
||||
{
|
||||
jc = get_le32(b + ic + 1) + ic + 1;
|
||||
if (jc < size) {
|
||||
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
buf[b[ic+1]] |= 1;
|
||||
} else
|
||||
buf[b[ic + 1]] |= 1;
|
||||
}
|
||||
|
||||
if (getcto(f, buf) < 0)
|
||||
@ -76,35 +70,31 @@ static int F(Filter *f)
|
||||
}
|
||||
const unsigned char cto8 = f->cto;
|
||||
#ifdef U
|
||||
const unsigned cto = (unsigned)f->cto << 24;
|
||||
const unsigned cto = (unsigned) f->cto << 24;
|
||||
#endif
|
||||
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
{
|
||||
if (!COND(b,ic))
|
||||
for (ic = 0; ic < size - 5; ic++) {
|
||||
if (!COND(b, ic))
|
||||
continue;
|
||||
jc = get_le32(b+ic+1)+ic+1;
|
||||
jc = get_le32(b + ic + 1) + ic + 1;
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size)
|
||||
{
|
||||
if (jc < size) {
|
||||
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||
#ifdef U
|
||||
set_be32(b+ic+1,jc+addvalue+cto);
|
||||
set_be32(b + ic + 1, jc + addvalue + cto);
|
||||
#endif
|
||||
if (ic - lastnoncall < 5)
|
||||
{
|
||||
if (ic - lastnoncall < 5) {
|
||||
// check the last 4 bytes before this call
|
||||
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;
|
||||
if (kc)
|
||||
{
|
||||
if (kc) {
|
||||
#ifdef U
|
||||
// restore original
|
||||
set_le32(b+ic+1,jc-ic-1);
|
||||
set_le32(b + ic + 1, jc - ic - 1);
|
||||
#endif
|
||||
if (b[ic+1] == cto8)
|
||||
return 1; // fail - buffer not restored
|
||||
if (b[ic + 1] == cto8)
|
||||
return 1; // fail - buffer not restored
|
||||
lastnoncall = ic;
|
||||
noncalls2++;
|
||||
continue;
|
||||
@ -112,11 +102,9 @@ static int F(Filter *f)
|
||||
}
|
||||
calls++;
|
||||
ic += 4;
|
||||
lastcall = ic+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(b[ic+1] != cto8); // this should not happen
|
||||
lastcall = ic + 1;
|
||||
} else {
|
||||
assert(b[ic + 1] != cto8); // this should not happen
|
||||
lastnoncall = ic;
|
||||
noncalls++;
|
||||
}
|
||||
@ -133,40 +121,34 @@ static int F(Filter *f)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// unfilter
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef U
|
||||
static int U(Filter *f)
|
||||
{
|
||||
static int U(Filter *f) {
|
||||
byte *b = f->buf;
|
||||
const unsigned size5 = f->buf_len - 5;
|
||||
const unsigned addvalue = f->addvalue;
|
||||
const unsigned cto = (unsigned)f->cto << 24;
|
||||
const unsigned cto = (unsigned) f->cto << 24;
|
||||
|
||||
unsigned ic, jc;
|
||||
|
||||
for (ic = 0; ic < size5; ic++)
|
||||
if (COND(b,ic))
|
||||
{
|
||||
jc = get_be32(b+ic+1);
|
||||
if (b[ic+1] == f->cto)
|
||||
{
|
||||
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
|
||||
if (COND(b, ic)) {
|
||||
jc = get_be32(b + ic + 1);
|
||||
if (b[ic + 1] == f->cto) {
|
||||
set_le32(b + ic + 1, jc - ic - 1 - addvalue - cto);
|
||||
f->calls++;
|
||||
ic += 4;
|
||||
f->lastcall = ic+1;
|
||||
}
|
||||
else
|
||||
f->lastcall = ic + 1;
|
||||
} else
|
||||
f->noncalls++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#undef F
|
||||
#undef U
|
||||
|
||||
|
||||
@ -29,14 +29,11 @@
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// filter / scan
|
||||
**************************************************************************/
|
||||
|
||||
static int F(Filter *f)
|
||||
{
|
||||
static int F(Filter *f) {
|
||||
#ifdef U
|
||||
// filter
|
||||
byte *b = f->buf;
|
||||
@ -54,20 +51,17 @@ static int F(Filter *f)
|
||||
// find a 16 MiB large empty address space
|
||||
{
|
||||
unsigned char buf[256];
|
||||
memset(buf,0,256);
|
||||
memset(buf, 0, 256);
|
||||
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
{
|
||||
if (!COND(b,ic,lastcall))
|
||||
for (ic = 0; ic < size - 5; ic++) {
|
||||
if (!COND(b, ic, lastcall))
|
||||
continue;
|
||||
jc = get_le32(b+ic+1)+ic+1;
|
||||
if (jc < size)
|
||||
{
|
||||
jc = get_le32(b + ic + 1) + ic + 1;
|
||||
if (jc < size) {
|
||||
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
buf[b[ic+1]] |= 1;
|
||||
} else
|
||||
buf[b[ic + 1]] |= 1;
|
||||
}
|
||||
|
||||
if (getcto(f, buf) < 0)
|
||||
@ -75,35 +69,31 @@ static int F(Filter *f)
|
||||
}
|
||||
const unsigned char cto8 = f->cto;
|
||||
#ifdef U
|
||||
const unsigned cto = (unsigned)f->cto << 24;
|
||||
const unsigned cto = (unsigned) f->cto << 24;
|
||||
#endif
|
||||
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
{
|
||||
if (!COND(b,ic,lastcall))
|
||||
for (ic = 0; ic < size - 5; ic++) {
|
||||
if (!COND(b, ic, lastcall))
|
||||
continue;
|
||||
jc = get_le32(b+ic+1)+ic+1;
|
||||
jc = get_le32(b + ic + 1) + ic + 1;
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size)
|
||||
{
|
||||
if (jc < size) {
|
||||
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||
#ifdef U
|
||||
set_be32(b+ic+1,jc+addvalue+cto);
|
||||
set_be32(b + ic + 1, jc + addvalue + cto);
|
||||
#endif
|
||||
if (ic - lastnoncall < 5)
|
||||
{
|
||||
if (ic - lastnoncall < 5) {
|
||||
// check the last 4 bytes before this call
|
||||
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;
|
||||
if (kc)
|
||||
{
|
||||
if (kc) {
|
||||
#ifdef U
|
||||
// restore original
|
||||
set_le32(b+ic+1,jc-ic-1);
|
||||
set_le32(b + ic + 1, jc - ic - 1);
|
||||
#endif
|
||||
if (b[ic+1] == cto8)
|
||||
return 1; // fail - buffer not restored
|
||||
if (b[ic + 1] == cto8)
|
||||
return 1; // fail - buffer not restored
|
||||
lastnoncall = ic;
|
||||
noncalls2++;
|
||||
continue;
|
||||
@ -111,11 +101,9 @@ static int F(Filter *f)
|
||||
}
|
||||
calls++;
|
||||
ic += 4;
|
||||
lastcall = ic+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(b[ic+1] != cto8); // this should not happen
|
||||
lastcall = ic + 1;
|
||||
} else {
|
||||
assert(b[ic + 1] != cto8); // this should not happen
|
||||
lastnoncall = ic;
|
||||
noncalls++;
|
||||
}
|
||||
@ -132,40 +120,34 @@ static int F(Filter *f)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// unfilter
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef U
|
||||
static int U(Filter *f)
|
||||
{
|
||||
static int U(Filter *f) {
|
||||
byte *b = f->buf;
|
||||
const unsigned size5 = f->buf_len - 5;
|
||||
const unsigned addvalue = f->addvalue;
|
||||
const unsigned cto = (unsigned)f->cto << 24;
|
||||
// unsigned lastcall = 0; // lastcall is not used in COND macro
|
||||
const unsigned cto = (unsigned) f->cto << 24;
|
||||
// unsigned lastcall = 0; // lastcall is not used in COND macro
|
||||
unsigned ic, jc;
|
||||
|
||||
for (ic = 0; ic < size5; ic++)
|
||||
if (COND(b,ic,lastcall))
|
||||
{
|
||||
jc = get_be32(b+ic+1);
|
||||
if (b[ic+1] == f->cto)
|
||||
{
|
||||
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
|
||||
if (COND(b, ic, lastcall)) {
|
||||
jc = get_be32(b + ic + 1);
|
||||
if (b[ic + 1] == f->cto) {
|
||||
set_le32(b + ic + 1, jc - ic - 1 - addvalue - cto);
|
||||
f->calls++;
|
||||
ic += 4;
|
||||
f->lastcall = ic+1;
|
||||
}
|
||||
else
|
||||
f->lastcall = ic + 1;
|
||||
} else
|
||||
f->noncalls++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#undef F
|
||||
#undef U
|
||||
|
||||
|
||||
@ -29,61 +29,43 @@
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#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
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// filter / scan
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef U //{
|
||||
#define NOFILT 0 // no filter
|
||||
#define FNOMRU 1 // filter, but not using mru
|
||||
#define MRUFLT 2 // mru filter
|
||||
#ifdef U //{
|
||||
#define NOFILT 0 // no filter
|
||||
#define FNOMRU 1 // filter, but not using mru
|
||||
#define MRUFLT 2 // mru filter
|
||||
|
||||
static unsigned
|
||||
f80_call(Filter const *f)
|
||||
{
|
||||
return (1+ (0x0f & f->id)) % 3;
|
||||
}
|
||||
static unsigned f80_call(Filter const *f) { return (1 + (0x0f & f->id)) % 3; }
|
||||
|
||||
static unsigned
|
||||
f80_jmp1(Filter const *f)
|
||||
{
|
||||
return ((1+ (0x0f & f->id)) / 3) % 3;
|
||||
}
|
||||
static unsigned f80_jmp1(Filter const *f) { return ((1 + (0x0f & f->id)) / 3) % 3; }
|
||||
|
||||
static unsigned
|
||||
f80_jcc2(Filter const *f)
|
||||
{
|
||||
return f80_jmp1(f);
|
||||
}
|
||||
static unsigned 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.
|
||||
static void
|
||||
update_mru(
|
||||
const unsigned jc, // destination address
|
||||
const int kh, // mru[kh] is slot where found
|
||||
unsigned mru[N_MRU], // circular buffer of most recent destinations
|
||||
int &hand, // mru[hand] is most recent destination
|
||||
int &tail // mru[tail] is beyond oldest destination ("cold cache" startup)
|
||||
)
|
||||
{
|
||||
static void update_mru(const unsigned jc, // destination address
|
||||
const int kh, // mru[kh] is slot where found
|
||||
unsigned mru[N_MRU], // circular buffer of most recent destinations
|
||||
int &hand, // mru[hand] is most recent destination
|
||||
int &tail // mru[tail] is beyond oldest destination ("cold cache" startup)
|
||||
) {
|
||||
if (0 > --hand) {
|
||||
hand = N_MRU -1;
|
||||
hand = N_MRU - 1;
|
||||
}
|
||||
const unsigned t = mru[hand]; // entry which will be overwritten by jc
|
||||
if (0!=t) { // have seen at least N_MRU destinations
|
||||
const unsigned t = mru[hand]; // entry which will be overwritten by jc
|
||||
if (0 != t) { // have seen at least N_MRU destinations
|
||||
mru[kh] = t;
|
||||
}
|
||||
else { // "cold cache": keep active region contiguous
|
||||
} else { // "cold cache": keep active region contiguous
|
||||
if (0 > --tail) {
|
||||
tail = N_MRU -1;
|
||||
tail = N_MRU - 1;
|
||||
}
|
||||
const unsigned t2 = mru[tail];
|
||||
mru[tail] = 0;
|
||||
@ -91,11 +73,9 @@ update_mru(
|
||||
}
|
||||
mru[hand] = jc;
|
||||
}
|
||||
#endif //}
|
||||
#endif //}
|
||||
|
||||
|
||||
static int F(Filter *f)
|
||||
{
|
||||
static int F(Filter *f) {
|
||||
#ifdef U
|
||||
// filter
|
||||
byte *const b = f->buf;
|
||||
@ -108,9 +88,10 @@ static int F(Filter *f)
|
||||
unsigned ic, jc, kc;
|
||||
unsigned calls = 0, noncalls = 0, noncalls2 = 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_jmp1 = f80_jmp1(f);
|
||||
const unsigned f_jcc2 = f80_jcc2(f);
|
||||
@ -118,22 +99,20 @@ static int F(Filter *f)
|
||||
int hand = 0, tail = 0;
|
||||
unsigned mru[N_MRU];
|
||||
memset(&mru[0], 0, sizeof(mru));
|
||||
assert(N_MRU<=256);
|
||||
f->n_mru = (MRUFLT==f_call || MRUFLT==f_jmp1 || MRUFLT==f_jcc2) ?
|
||||
N_MRU : 0;
|
||||
#endif //}
|
||||
assert(N_MRU <= 256);
|
||||
f->n_mru = (MRUFLT == f_call || MRUFLT == f_jmp1 || MRUFLT == f_jcc2) ? N_MRU : 0;
|
||||
#endif //}
|
||||
|
||||
// FIXME: We must fit into 8 MiB because we steal one bit.
|
||||
// find a 16 MiB large empty address space
|
||||
{
|
||||
int which;
|
||||
unsigned char buf[256];
|
||||
memset(buf,0,256);
|
||||
memset(buf, 0, 256);
|
||||
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
if (CONDF(which,b,ic,lastcall) && get_le32(b+ic+1)+ic+1 >= size)
|
||||
{
|
||||
buf[b[ic+1]] |= 1;
|
||||
if (CONDF(which, b, ic, lastcall) && get_le32(b + ic + 1) + ic + 1 >= size) {
|
||||
buf[b[ic + 1]] |= 1;
|
||||
}
|
||||
UNUSED(which);
|
||||
|
||||
@ -142,37 +121,33 @@ static int F(Filter *f)
|
||||
}
|
||||
const unsigned char cto8 = f->cto;
|
||||
#ifdef U
|
||||
const unsigned cto = (unsigned)f->cto << 24;
|
||||
const unsigned cto = (unsigned) f->cto << 24;
|
||||
#endif
|
||||
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
{
|
||||
for (ic = 0; ic < size - 5; ic++) {
|
||||
int which;
|
||||
int f_on = 0;
|
||||
if (!CONDF(which,b,ic,lastcall))
|
||||
if (!CONDF(which, b, ic, lastcall))
|
||||
continue;
|
||||
++wtally[which];
|
||||
jc = get_le32(b+ic+1)+ic+1;
|
||||
jc = get_le32(b + ic + 1) + ic + 1;
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size)
|
||||
{
|
||||
if (jc < size) {
|
||||
#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
|
||||
// varies. Because we store the destination (or its mru index)
|
||||
// in be32 big endian format, the low-addressed bytes
|
||||
// will tend to be constant. Swap prefix and opcode
|
||||
// so that constants are together for better compression.
|
||||
unsigned char const t =
|
||||
b[ic-1];
|
||||
b[ic-1] = b[ic];
|
||||
b[ic] = t;
|
||||
unsigned char const t = b[ic - 1];
|
||||
b[ic - 1] = b[ic];
|
||||
b[ic] = t;
|
||||
}
|
||||
// FIXME [?]: Extend to 8 bytes if "ADD ESP, byte 4*n" follows CALL.
|
||||
// This will require two related cto's (consecutive, or otherwise).
|
||||
if ((0==which && MRUFLT==f_call)
|
||||
|| (1==which && MRUFLT==f_jmp1)
|
||||
|| (2==which && MRUFLT==f_jcc2) ) {
|
||||
// FIXME [?]: Extend to 8 bytes if "ADD ESP, byte 4*n" follows CALL.
|
||||
// This will require two related cto's (consecutive, or otherwise).
|
||||
if ((0 == which && MRUFLT == f_call) || (1 == which && MRUFLT == f_jmp1) ||
|
||||
(2 == which && MRUFLT == f_jcc2)) {
|
||||
f_on = 1;
|
||||
// Recode the destination: narrower mru indices
|
||||
// should compress better than wider addresses.
|
||||
@ -184,62 +159,55 @@ static int F(Filter *f)
|
||||
kh -= N_MRU;
|
||||
}
|
||||
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);
|
||||
break;
|
||||
}
|
||||
}
|
||||
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.
|
||||
if (0 > --hand) {
|
||||
hand = N_MRU -1;
|
||||
hand = N_MRU - 1;
|
||||
}
|
||||
mru[hand] = jc;
|
||||
}
|
||||
} else
|
||||
if ((0==which && NOFILT!=f_call)
|
||||
|| (1==which && NOFILT!=f_jmp1)
|
||||
|| (2==which && NOFILT!=f_jcc2) ) {
|
||||
} else if ((0 == which && NOFILT != f_call) || (1 == which && NOFILT != f_jmp1) ||
|
||||
(2 == which && NOFILT != f_jcc2)) {
|
||||
f_on = 1;
|
||||
set_be32(b+ic+1, jc+cto);
|
||||
set_be32(b + ic + 1, jc + cto);
|
||||
}
|
||||
#endif
|
||||
if (f_on) {
|
||||
if (ic - lastnoncall < 5)
|
||||
{
|
||||
// check the last 4 bytes before this call
|
||||
for (kc = 4; kc; kc--)
|
||||
if (CONDF(which,b,ic-kc,lastcall) && b[ic-kc+1] == cto8)
|
||||
break;
|
||||
if (kc)
|
||||
{
|
||||
#ifdef U
|
||||
// restore original
|
||||
if (2==which) {
|
||||
// Unswap prefix and opcode for 6-byte Jcc <disp32>
|
||||
unsigned char const 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;
|
||||
if (ic - lastnoncall < 5) {
|
||||
// check the last 4 bytes before this call
|
||||
for (kc = 4; kc; kc--)
|
||||
if (CONDF(which, b, ic - kc, lastcall) && b[ic - kc + 1] == cto8)
|
||||
break;
|
||||
if (kc) {
|
||||
#ifdef U
|
||||
// restore original
|
||||
if (2 == which) {
|
||||
// Unswap prefix and opcode for 6-byte Jcc <disp32>
|
||||
unsigned char const 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;
|
||||
}
|
||||
calls++;
|
||||
ic += 4;
|
||||
lastcall = ic+1;
|
||||
}
|
||||
calls++;
|
||||
ic += 4;
|
||||
lastcall = ic + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(b[ic+1] != cto8); // this should not happen
|
||||
} else {
|
||||
assert(b[ic + 1] != cto8); // this should not happen
|
||||
lastnoncall = ic;
|
||||
noncalls++;
|
||||
}
|
||||
@ -258,19 +226,17 @@ static int F(Filter *f)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// unfilter
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef U
|
||||
static int U(Filter *f)
|
||||
{
|
||||
static int U(Filter *f) {
|
||||
unsigned ic, jc;
|
||||
|
||||
byte *const b = f->buf;
|
||||
const unsigned size5 = f->buf_len - 5;
|
||||
const unsigned cto = (unsigned)f->cto << 24;
|
||||
const unsigned cto = (unsigned) f->cto << 24;
|
||||
unsigned lastcall = 0;
|
||||
int hand = 0, tail = 0;
|
||||
const unsigned f_call = f80_call(f);
|
||||
@ -282,58 +248,50 @@ static int U(Filter *f)
|
||||
|
||||
for (ic = 0; ic < size5; ic++) {
|
||||
int which;
|
||||
if (CONDU(which,b,ic,lastcall))
|
||||
{
|
||||
if (CONDU(which, b, ic, lastcall)) {
|
||||
unsigned f_on = 0;
|
||||
jc = get_be32(b+ic+1) - cto;
|
||||
if (b[ic+1] == f->cto)
|
||||
{
|
||||
if ((0==which && MRUFLT==f_call)
|
||||
|| (1==which && MRUFLT==f_jmp1)
|
||||
|| (2==which && MRUFLT==f_jcc2) ) {
|
||||
jc = get_be32(b + ic + 1) - cto;
|
||||
if (b[ic + 1] == f->cto) {
|
||||
if ((0 == which && MRUFLT == f_call) || (1 == which && MRUFLT == f_jmp1) ||
|
||||
(2 == which && MRUFLT == f_jcc2)) {
|
||||
f_on = 1;
|
||||
if (1&jc) { // 1st time at this destination
|
||||
jc >>= 1;
|
||||
if (0 > --hand) {
|
||||
hand = N_MRU -1;
|
||||
}
|
||||
mru[hand] = jc;
|
||||
if (1 & jc) { // 1st time at this destination
|
||||
jc >>= 1;
|
||||
if (0 > --hand) {
|
||||
hand = N_MRU - 1;
|
||||
}
|
||||
else { // not 1st time at this destination
|
||||
jc >>= 1;
|
||||
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);
|
||||
mru[hand] = jc;
|
||||
} else { // not 1st time at this destination
|
||||
jc >>= 1;
|
||||
if (N_MRU <= jc) {
|
||||
throwCompressedDataViolation();
|
||||
}
|
||||
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) ) {
|
||||
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);
|
||||
} else if ((0 == which && NOFILT != f_call) || (1 == which && NOFILT != f_jmp1) ||
|
||||
(2 == which && NOFILT != f_jcc2)) {
|
||||
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>
|
||||
unsigned char const t =
|
||||
b[ic-1];
|
||||
b[ic-1] = b[ic];
|
||||
b[ic] = t;
|
||||
unsigned char const t = b[ic - 1];
|
||||
b[ic - 1] = b[ic];
|
||||
b[ic] = t;
|
||||
}
|
||||
|
||||
if (f_on) {
|
||||
f->calls++;
|
||||
ic += 4;
|
||||
f->lastcall = lastcall = ic+1;
|
||||
f->lastcall = lastcall = ic + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
f->noncalls++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,14 +29,11 @@
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// filter / scan
|
||||
**************************************************************************/
|
||||
|
||||
static int F(Filter *f)
|
||||
{
|
||||
static int F(Filter *f) {
|
||||
#ifdef U
|
||||
// filter
|
||||
byte *b = f->buf;
|
||||
@ -55,20 +52,17 @@ static int F(Filter *f)
|
||||
// find a 16 MiB large empty address space
|
||||
{
|
||||
unsigned char buf[256];
|
||||
memset(buf,0,256);
|
||||
memset(buf, 0, 256);
|
||||
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
{
|
||||
if (!COND(b,ic,lastcall,id))
|
||||
for (ic = 0; ic < size - 5; ic++) {
|
||||
if (!COND(b, ic, lastcall, id))
|
||||
continue;
|
||||
jc = get_le32(b+ic+1)+ic+1;
|
||||
if (jc < size)
|
||||
{
|
||||
jc = get_le32(b + ic + 1) + ic + 1;
|
||||
if (jc < size) {
|
||||
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
buf[b[ic+1]] |= 1;
|
||||
} else
|
||||
buf[b[ic + 1]] |= 1;
|
||||
}
|
||||
|
||||
if (getcto(f, buf) < 0)
|
||||
@ -76,35 +70,31 @@ static int F(Filter *f)
|
||||
}
|
||||
const unsigned char cto8 = f->cto;
|
||||
#ifdef U
|
||||
const unsigned cto = (unsigned)f->cto << 24;
|
||||
const unsigned cto = (unsigned) f->cto << 24;
|
||||
#endif
|
||||
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
{
|
||||
if (!COND(b,ic,lastcall,id))
|
||||
for (ic = 0; ic < size - 5; ic++) {
|
||||
if (!COND(b, ic, lastcall, id))
|
||||
continue;
|
||||
jc = get_le32(b+ic+1)+ic+1;
|
||||
jc = get_le32(b + ic + 1) + ic + 1;
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size)
|
||||
{
|
||||
if (jc < size) {
|
||||
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||
#ifdef U
|
||||
set_be32(b+ic+1,jc+addvalue+cto);
|
||||
set_be32(b + ic + 1, jc + addvalue + cto);
|
||||
#endif
|
||||
if (ic - lastnoncall < 5)
|
||||
{
|
||||
if (ic - lastnoncall < 5) {
|
||||
// check the last 4 bytes before this call
|
||||
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;
|
||||
if (kc)
|
||||
{
|
||||
if (kc) {
|
||||
#ifdef U
|
||||
// restore original
|
||||
set_le32(b+ic+1,jc-ic-1);
|
||||
set_le32(b + ic + 1, jc - ic - 1);
|
||||
#endif
|
||||
if (b[ic+1] == cto8)
|
||||
return 1; // fail - buffer not restored
|
||||
if (b[ic + 1] == cto8)
|
||||
return 1; // fail - buffer not restored
|
||||
lastnoncall = ic;
|
||||
noncalls2++;
|
||||
continue;
|
||||
@ -112,11 +102,9 @@ static int F(Filter *f)
|
||||
}
|
||||
calls++;
|
||||
ic += 4;
|
||||
lastcall = ic+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(b[ic+1] != cto8); // this should not happen
|
||||
lastcall = ic + 1;
|
||||
} else {
|
||||
assert(b[ic + 1] != cto8); // this should not happen
|
||||
lastnoncall = ic;
|
||||
noncalls++;
|
||||
}
|
||||
@ -133,42 +121,36 @@ static int F(Filter *f)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// unfilter
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef U
|
||||
static int U(Filter *f)
|
||||
{
|
||||
static int U(Filter *f) {
|
||||
byte *b = f->buf;
|
||||
const unsigned size5 = f->buf_len - 5;
|
||||
const unsigned addvalue = f->addvalue;
|
||||
const unsigned cto = (unsigned)f->cto << 24;
|
||||
const unsigned cto = (unsigned) f->cto << 24;
|
||||
const unsigned id = f->id;
|
||||
unsigned lastcall = 0;
|
||||
|
||||
unsigned ic, jc;
|
||||
|
||||
for (ic = 0; ic < size5; ic++)
|
||||
if (COND(b,ic,lastcall,id))
|
||||
{
|
||||
jc = get_be32(b+ic+1);
|
||||
if (b[ic+1] == f->cto)
|
||||
{
|
||||
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
|
||||
if (COND(b, ic, lastcall, id)) {
|
||||
jc = get_be32(b + ic + 1);
|
||||
if (b[ic + 1] == f->cto) {
|
||||
set_le32(b + ic + 1, jc - ic - 1 - addvalue - cto);
|
||||
f->calls++;
|
||||
ic += 4;
|
||||
f->lastcall = lastcall = ic+1;
|
||||
}
|
||||
else
|
||||
f->lastcall = lastcall = ic + 1;
|
||||
} else
|
||||
f->noncalls++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#undef F
|
||||
#undef U
|
||||
|
||||
|
||||
@ -25,145 +25,118 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// 16-bit call-/swaptrick ("naive")
|
||||
**************************************************************************/
|
||||
|
||||
#define CTSW16(f, cond1, cond2, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 3; \
|
||||
do { \
|
||||
if (cond1) \
|
||||
{ \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
b += 2 - 1; \
|
||||
} \
|
||||
else if (cond2) \
|
||||
{ \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b)); \
|
||||
f->calls++; \
|
||||
b += 2 - 1; \
|
||||
} \
|
||||
} while (++b < b_end); \
|
||||
if (f->lastcall) f->lastcall += 2; \
|
||||
#define CTSW16(f, cond1, cond2, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 3; \
|
||||
do { \
|
||||
if (cond1) { \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
b += 2 - 1; \
|
||||
} else if (cond2) { \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b)); \
|
||||
f->calls++; \
|
||||
b += 2 - 1; \
|
||||
} \
|
||||
} while (++b < b_end); \
|
||||
if (f->lastcall) \
|
||||
f->lastcall += 2; \
|
||||
return 0;
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
#undef CTSW16
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// 32-bit call-/swaptrick ("naive")
|
||||
**************************************************************************/
|
||||
|
||||
#define CTSW32(f, cond1, cond2, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 5; \
|
||||
do { \
|
||||
if (cond1) \
|
||||
{ \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
b += 4 - 1; \
|
||||
} \
|
||||
else if (cond2) \
|
||||
{ \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b)); \
|
||||
f->calls++; \
|
||||
b += 4 - 1; \
|
||||
} \
|
||||
} while (++b < b_end); \
|
||||
if (f->lastcall) f->lastcall += 4; \
|
||||
#define CTSW32(f, cond1, cond2, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 5; \
|
||||
do { \
|
||||
if (cond1) { \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
b += 4 - 1; \
|
||||
} else if (cond2) { \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b)); \
|
||||
f->calls++; \
|
||||
b += 4 - 1; \
|
||||
} \
|
||||
} while (++b < b_end); \
|
||||
if (f->lastcall) \
|
||||
f->lastcall += 4; \
|
||||
return 0;
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
#undef CTSW32
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
@ -25,21 +25,14 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "../conf.h"
|
||||
#include "../filter.h"
|
||||
|
||||
static unsigned
|
||||
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))
|
||||
static unsigned 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))
|
||||
|
||||
/*************************************************************************
|
||||
// util
|
||||
@ -47,7 +40,6 @@ umin(const unsigned a, const unsigned b)
|
||||
|
||||
#include "getcto.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// simple filters: calltrick / swaptrick / delta / ...
|
||||
**************************************************************************/
|
||||
@ -60,86 +52,80 @@ umin(const unsigned a, const unsigned b)
|
||||
#include "sub16.h"
|
||||
#include "sub32.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// cto calltrick
|
||||
**************************************************************************/
|
||||
|
||||
#define COND(b,x) (b[x] == 0xe8)
|
||||
#define F f_cto32_e8_bswap_le
|
||||
#define U u_cto32_e8_bswap_le
|
||||
#define COND(b, x) (b[x] == 0xe8)
|
||||
#define F f_cto32_e8_bswap_le
|
||||
#define U u_cto32_e8_bswap_le
|
||||
#include "cto.h"
|
||||
#define F s_cto32_e8_bswap_le
|
||||
#define F s_cto32_e8_bswap_le
|
||||
#include "cto.h"
|
||||
#undef COND
|
||||
|
||||
#define COND(b,x) (b[x] == 0xe9)
|
||||
#define F f_cto32_e9_bswap_le
|
||||
#define U u_cto32_e9_bswap_le
|
||||
#define COND(b, x) (b[x] == 0xe9)
|
||||
#define F f_cto32_e9_bswap_le
|
||||
#define U u_cto32_e9_bswap_le
|
||||
#include "cto.h"
|
||||
#define F s_cto32_e9_bswap_le
|
||||
#define F s_cto32_e9_bswap_le
|
||||
#include "cto.h"
|
||||
#undef COND
|
||||
|
||||
#define COND(b,x) (b[x] == 0xe8 || b[x] == 0xe9)
|
||||
#define F f_cto32_e8e9_bswap_le
|
||||
#define U u_cto32_e8e9_bswap_le
|
||||
#define COND(b, x) (b[x] == 0xe8 || b[x] == 0xe9)
|
||||
#define F f_cto32_e8e9_bswap_le
|
||||
#define U u_cto32_e8e9_bswap_le
|
||||
#include "cto.h"
|
||||
#define F s_cto32_e8e9_bswap_le
|
||||
#define F s_cto32_e8e9_bswap_le
|
||||
#include "cto.h"
|
||||
#undef COND
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// cto calltrick with jmp
|
||||
**************************************************************************/
|
||||
|
||||
#define COND(b,x,lastcall) (b[x] == 0xe8 || b[x] == 0xe9)
|
||||
#define F f_ctoj32_e8e9_bswap_le
|
||||
#define U u_ctoj32_e8e9_bswap_le
|
||||
#define COND(b, x, lastcall) (b[x] == 0xe8 || b[x] == 0xe9)
|
||||
#define F f_ctoj32_e8e9_bswap_le
|
||||
#define U u_ctoj32_e8e9_bswap_le
|
||||
#include "ctoj.h"
|
||||
#define F s_ctoj32_e8e9_bswap_le
|
||||
#define F s_ctoj32_e8e9_bswap_le
|
||||
#include "ctoj.h"
|
||||
#undef COND
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// cto calltrick with jmp, optional jcc
|
||||
**************************************************************************/
|
||||
|
||||
#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 COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc)))
|
||||
#define F f_ctok32_e8e9_bswap_le
|
||||
#define U u_ctok32_e8e9_bswap_le
|
||||
#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 COND(b, x, lc, id) (COND1(b, x) || ((9 <= (0xf & (id))) && COND2(b, x, lc)))
|
||||
#define F f_ctok32_e8e9_bswap_le
|
||||
#define U u_ctok32_e8e9_bswap_le
|
||||
#include "ctok.h"
|
||||
#define F s_ctok32_e8e9_bswap_le
|
||||
#define F s_ctok32_e8e9_bswap_le
|
||||
#include "ctok.h"
|
||||
#undef COND
|
||||
#undef COND2
|
||||
#undef COND1
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// cto calltrick with jmp and jcc and relative renumbering
|
||||
**************************************************************************/
|
||||
|
||||
#define COND_CALL(which,b,x) ((which = 0), b[x] == 0xe8)
|
||||
#define COND_JMP( which,b,x) ((which = 1), b[x] == 0xe9)
|
||||
#define COND_JCC( which,b,lastcall,x,y,z) ((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 COND2(which,b,lastcall,x,y,z) COND_JCC(which,b,lastcall,x,y,z)
|
||||
#define COND_CALL(which, b, x) ((which = 0), b[x] == 0xe8)
|
||||
#define COND_JMP(which, b, x) ((which = 1), b[x] == 0xe9)
|
||||
#define COND_JCC(which, b, lastcall, x, y, z) \
|
||||
((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 COND2(which, b, lastcall, x, y, z) COND_JCC(which, b, lastcall, x, y, z)
|
||||
|
||||
#define CONDF(which,b,x,lastcall) \
|
||||
(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 CONDF(which, b, x, lastcall) (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 F f_ctojr32_e8e9_bswap_le
|
||||
#define U u_ctojr32_e8e9_bswap_le
|
||||
#define F f_ctojr32_e8e9_bswap_le
|
||||
#define U u_ctojr32_e8e9_bswap_le
|
||||
#include "ctojr.h"
|
||||
#define F s_ctojr32_e8e9_bswap_le
|
||||
#define F s_ctojr32_e8e9_bswap_le
|
||||
#include "ctojr.h"
|
||||
|
||||
#undef CONDU
|
||||
@ -150,24 +136,23 @@ umin(const unsigned a, const unsigned b)
|
||||
#undef COND_JMP
|
||||
#undef COND_CALL
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// PowerPC branch [incl. call] trick
|
||||
**************************************************************************/
|
||||
|
||||
#define COND(b,x) (18==(get_be32(b+x)>>26))
|
||||
#define F f_ppcbxx
|
||||
#define U u_ppcbxx
|
||||
#define COND(b, x) (18 == (get_be32(b + x) >> 26))
|
||||
#define F f_ppcbxx
|
||||
#define U u_ppcbxx
|
||||
#include "ppcbxx.h"
|
||||
#define F s_ppcbxx
|
||||
#define F s_ppcbxx
|
||||
#include "ppcbxx.h"
|
||||
#undef COND
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// database for use in class Filter
|
||||
**************************************************************************/
|
||||
|
||||
// clang-format off
|
||||
/*static*/ const FilterImpl::FilterEntry FilterImpl::filters[] = {
|
||||
// no filter
|
||||
{ 0x00, 0, 0, nullptr, nullptr, nullptr },
|
||||
@ -265,6 +250,7 @@ umin(const unsigned a, const unsigned b)
|
||||
// PowerPC branch+call trick
|
||||
{ 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
/*static*/ const int FilterImpl::n_filters = TABLESIZE(filters);
|
||||
|
||||
|
||||
@ -25,22 +25,16 @@
|
||||
<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;
|
||||
|
||||
if (f->preferred_ctos)
|
||||
{
|
||||
for (const int *pc = f->preferred_ctos; *pc >= 0; pc++)
|
||||
{
|
||||
if (*pc < n && buf[*pc] == 0)
|
||||
{
|
||||
if (f->preferred_ctos) {
|
||||
for (const int *pc = f->preferred_ctos; *pc >= 0; pc++) {
|
||||
if (*pc < n && buf[*pc] == 0) {
|
||||
ic = *pc;
|
||||
break;
|
||||
}
|
||||
@ -60,7 +54,7 @@ static int getcto(Filter *f, const byte *buf, const int n=256)
|
||||
break;
|
||||
|
||||
if (ic >= n)
|
||||
//throwCantPack("call trick problem");
|
||||
// throwCantPack("call trick problem");
|
||||
return -1;
|
||||
|
||||
f->cto = (byte) ic;
|
||||
|
||||
@ -29,16 +29,13 @@
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// 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
|
||||
// filter
|
||||
byte *b = f->buf;
|
||||
@ -47,8 +44,8 @@ static int F(Filter *f)
|
||||
// scan
|
||||
const byte *b = f->buf;
|
||||
#endif
|
||||
const unsigned size = umin(f->buf_len, 0u - (~0u<<(32 - (6+ W_CTO))));
|
||||
const unsigned size4 = size -4;
|
||||
const unsigned size = umin(f->buf_len, 0u - (~0u << (32 - (6 + W_CTO))));
|
||||
const unsigned size4 = size - 4;
|
||||
|
||||
unsigned ic;
|
||||
unsigned calls = 0, noncalls = 0;
|
||||
@ -58,18 +55,19 @@ static int F(Filter *f)
|
||||
{
|
||||
unsigned char buf[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(buf , 0, WW);
|
||||
memset(buf, 0, WW);
|
||||
memset(buf + WW, 1, 256 - WW);
|
||||
|
||||
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) {
|
||||
unsigned const off = (int)(get_be32(b+ic)<<6) >>6;
|
||||
if (size <= (off & (~0u<<2))+ic) {
|
||||
buf[(~(~0u<<W_CTO)) & (off>>(26 - W_CTO))] |= 1;
|
||||
++wbuf[0xff&(off>>18)];
|
||||
for (ic = 0; ic <= size4; ic += 4)
|
||||
if (COND(b, ic)) {
|
||||
unsigned const off = (int) (get_be32(b + ic) << 6) >> 6;
|
||||
if (size <= (off & (~0u << 2)) + ic) {
|
||||
buf[(~(~0u << W_CTO)) & (off >> (26 - W_CTO))] |= 1;
|
||||
++wbuf[0xff & (off >> 18)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getcto(f, buf) < 0) {
|
||||
#if (W_CTO != 0)
|
||||
@ -81,29 +79,30 @@ static int F(Filter *f)
|
||||
}
|
||||
const unsigned char cto8 = f->cto;
|
||||
#ifdef U
|
||||
const unsigned cto = (unsigned)f->cto << (24+2 - W_CTO);
|
||||
const unsigned cto = (unsigned) f->cto << (24 + 2 - W_CTO);
|
||||
#endif
|
||||
|
||||
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) {
|
||||
unsigned const word = get_be32(b+ic);
|
||||
unsigned const off = (int)(word<<6) >>6;
|
||||
unsigned const jc = (off & (~0u<<2))+ic;
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size) {
|
||||
for (ic = 0; ic <= size4; ic += 4)
|
||||
if (COND(b, ic)) {
|
||||
unsigned const word = get_be32(b + ic);
|
||||
unsigned const off = (int) (word << 6) >> 6;
|
||||
unsigned const jc = (off & (~0u << 2)) + ic;
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size) {
|
||||
#ifdef U
|
||||
set_be32(b+ic,(0xfc000003&word) | (jc+addvalue+cto));
|
||||
set_be32(b + ic, (0xfc000003 & word) | (jc + addvalue + cto));
|
||||
#endif
|
||||
calls++;
|
||||
lastcall = ic;
|
||||
}
|
||||
else {
|
||||
calls++;
|
||||
lastcall = ic;
|
||||
} else {
|
||||
#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
|
||||
lastnoncall = ic;
|
||||
noncalls++;
|
||||
lastnoncall = ic;
|
||||
noncalls++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f->calls = calls;
|
||||
f->noncalls = noncalls;
|
||||
@ -117,37 +116,34 @@ static int F(Filter *f)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// unfilter
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef U
|
||||
static int U(Filter *f)
|
||||
{
|
||||
static int U(Filter *f) {
|
||||
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;
|
||||
|
||||
unsigned ic;
|
||||
|
||||
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) {
|
||||
unsigned const word = get_be32(b+ic);
|
||||
if ((~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) == (unsigned) f->cto) {
|
||||
unsigned const jc = word & (~(~0u<<(26 - W_CTO)) & (~0u<<2));
|
||||
set_be32(b+ic, (0xfc000003&word)|(0x03fffffc&(jc-ic-addvalue)));
|
||||
f->calls++;
|
||||
f->lastcall = ic;
|
||||
for (ic = 0; ic <= size4; ic += 4)
|
||||
if (COND(b, ic)) {
|
||||
unsigned const word = get_be32(b + ic);
|
||||
if ((~(~0u << W_CTO) & (word >> (24 + 2 - W_CTO))) == (unsigned) f->cto) {
|
||||
unsigned const jc = word & (~(~0u << (26 - W_CTO)) & (~0u << 2));
|
||||
set_be32(b + ic, (0xfc000003 & word) | (0x03fffffc & (jc - ic - addvalue)));
|
||||
f->calls++;
|
||||
f->lastcall = ic;
|
||||
} else {
|
||||
f->noncalls++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
f->noncalls++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#undef F
|
||||
#undef U
|
||||
|
||||
|
||||
@ -25,58 +25,60 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#define SUB(f, N, T, get, set) \
|
||||
byte *b = f->buf; \
|
||||
unsigned l = f->buf_len / sizeof(T); \
|
||||
int i; \
|
||||
T d[N]; \
|
||||
\
|
||||
i = N - 1; do d[i] = 0; while (--i >= 0); \
|
||||
\
|
||||
i = N - 1; \
|
||||
do { \
|
||||
T delta = (T) (get(b) - d[i]); \
|
||||
set(b, delta); \
|
||||
d[i] = (T) (d[i] + delta); \
|
||||
b += sizeof(T); \
|
||||
if (--i < 0) \
|
||||
i = N - 1; \
|
||||
} while (--l > 0); \
|
||||
f->calls = (f->buf_len / sizeof(T)) - N; \
|
||||
assert((int)f->calls > 0); \
|
||||
#define SUB(f, N, T, get, set) \
|
||||
byte *b = f->buf; \
|
||||
unsigned l = f->buf_len / sizeof(T); \
|
||||
int i; \
|
||||
T d[N]; \
|
||||
\
|
||||
i = N - 1; \
|
||||
do \
|
||||
d[i] = 0; \
|
||||
while (--i >= 0); \
|
||||
\
|
||||
i = N - 1; \
|
||||
do { \
|
||||
T delta = (T) (get(b) - d[i]); \
|
||||
set(b, delta); \
|
||||
d[i] = (T) (d[i] + delta); \
|
||||
b += sizeof(T); \
|
||||
if (--i < 0) \
|
||||
i = N - 1; \
|
||||
} while (--l > 0); \
|
||||
f->calls = (f->buf_len / sizeof(T)) - N; \
|
||||
assert((int) f->calls > 0); \
|
||||
return 0;
|
||||
|
||||
|
||||
#define ADD(f, N, T, get, set) \
|
||||
byte *b = f->buf; \
|
||||
unsigned l = f->buf_len / sizeof(T); \
|
||||
int i; \
|
||||
T d[N]; \
|
||||
\
|
||||
i = N - 1; do d[i] = 0; while (--i >= 0); \
|
||||
\
|
||||
i = N - 1; \
|
||||
do { \
|
||||
d[i] = (T) (d[i] + get(b)); \
|
||||
set(b, d[i]); \
|
||||
b += sizeof(T); \
|
||||
if (--i < 0) \
|
||||
i = N - 1; \
|
||||
} while (--l > 0); \
|
||||
f->calls = (f->buf_len / sizeof(T)) - N; \
|
||||
assert((int)f->calls > 0); \
|
||||
#define ADD(f, N, T, get, set) \
|
||||
byte *b = f->buf; \
|
||||
unsigned l = f->buf_len / sizeof(T); \
|
||||
int i; \
|
||||
T d[N]; \
|
||||
\
|
||||
i = N - 1; \
|
||||
do \
|
||||
d[i] = 0; \
|
||||
while (--i >= 0); \
|
||||
\
|
||||
i = N - 1; \
|
||||
do { \
|
||||
d[i] = (T) (d[i] + get(b)); \
|
||||
set(b, d[i]); \
|
||||
b += sizeof(T); \
|
||||
if (--i < 0) \
|
||||
i = N - 1; \
|
||||
} while (--l > 0); \
|
||||
f->calls = (f->buf_len / sizeof(T)) - N; \
|
||||
assert((int) f->calls > 0); \
|
||||
return 0;
|
||||
|
||||
|
||||
#define SCAN(f, N, T, get, set) \
|
||||
f->calls = (f->buf_len / sizeof(T)) - N; \
|
||||
assert((int)f->calls > 0); \
|
||||
#define SCAN(f, N, T, get, set) \
|
||||
f->calls = (f->buf_len / sizeof(T)) - N; \
|
||||
assert((int) f->calls > 0); \
|
||||
return 0;
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
@ -25,88 +25,46 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#include "sub.hh"
|
||||
|
||||
#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 SCAN16(f, N) SCAN(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 SCAN16(f, N) SCAN(f, N, unsigned short, get_le16, set_le16)
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
// filter
|
||||
static int f_sub16_1(Filter *f)
|
||||
{
|
||||
SUB16(f, 1)
|
||||
}
|
||||
static int f_sub16_1(Filter *f) { SUB16(f, 1) }
|
||||
|
||||
static int f_sub16_2(Filter *f)
|
||||
{
|
||||
SUB16(f, 2)
|
||||
}
|
||||
static int f_sub16_2(Filter *f) { SUB16(f, 2) }
|
||||
|
||||
static int f_sub16_3(Filter *f)
|
||||
{
|
||||
SUB16(f, 3)
|
||||
}
|
||||
|
||||
static int f_sub16_4(Filter *f)
|
||||
{
|
||||
SUB16(f, 4)
|
||||
}
|
||||
static int f_sub16_3(Filter *f) { SUB16(f, 3) }
|
||||
|
||||
static int f_sub16_4(Filter *f) { SUB16(f, 4) }
|
||||
|
||||
// unfilter
|
||||
static int u_sub16_1(Filter *f)
|
||||
{
|
||||
ADD16(f, 1)
|
||||
}
|
||||
static int u_sub16_1(Filter *f) { ADD16(f, 1) }
|
||||
|
||||
static int u_sub16_2(Filter *f)
|
||||
{
|
||||
ADD16(f, 2)
|
||||
}
|
||||
static int u_sub16_2(Filter *f) { ADD16(f, 2) }
|
||||
|
||||
static int u_sub16_3(Filter *f)
|
||||
{
|
||||
ADD16(f, 3)
|
||||
}
|
||||
|
||||
static int u_sub16_4(Filter *f)
|
||||
{
|
||||
ADD16(f, 4)
|
||||
}
|
||||
static int u_sub16_3(Filter *f) { ADD16(f, 3) }
|
||||
|
||||
static int u_sub16_4(Filter *f) { ADD16(f, 4) }
|
||||
|
||||
// scan
|
||||
static int s_sub16_1(Filter *f)
|
||||
{
|
||||
SCAN16(f, 1)
|
||||
}
|
||||
static int s_sub16_1(Filter *f) { SCAN16(f, 1) }
|
||||
|
||||
static int s_sub16_2(Filter *f)
|
||||
{
|
||||
SCAN16(f, 2)
|
||||
}
|
||||
static int s_sub16_2(Filter *f) { SCAN16(f, 2) }
|
||||
|
||||
static int s_sub16_3(Filter *f)
|
||||
{
|
||||
SCAN16(f, 3)
|
||||
}
|
||||
|
||||
static int s_sub16_4(Filter *f)
|
||||
{
|
||||
SCAN16(f, 4)
|
||||
}
|
||||
static int s_sub16_3(Filter *f) { SCAN16(f, 3) }
|
||||
|
||||
static int s_sub16_4(Filter *f) { SCAN16(f, 4) }
|
||||
|
||||
#undef SUB
|
||||
#undef ADD
|
||||
|
||||
@ -25,88 +25,46 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#include "sub.hh"
|
||||
|
||||
#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 SCAN32(f, N) SCAN(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 SCAN32(f, N) SCAN(f, N, unsigned int, get_le32, set_le32)
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
// filter
|
||||
static int f_sub32_1(Filter *f)
|
||||
{
|
||||
SUB32(f, 1)
|
||||
}
|
||||
static int f_sub32_1(Filter *f) { SUB32(f, 1) }
|
||||
|
||||
static int f_sub32_2(Filter *f)
|
||||
{
|
||||
SUB32(f, 2)
|
||||
}
|
||||
static int f_sub32_2(Filter *f) { SUB32(f, 2) }
|
||||
|
||||
static int f_sub32_3(Filter *f)
|
||||
{
|
||||
SUB32(f, 3)
|
||||
}
|
||||
|
||||
static int f_sub32_4(Filter *f)
|
||||
{
|
||||
SUB32(f, 4)
|
||||
}
|
||||
static int f_sub32_3(Filter *f) { SUB32(f, 3) }
|
||||
|
||||
static int f_sub32_4(Filter *f) { SUB32(f, 4) }
|
||||
|
||||
// unfilter
|
||||
static int u_sub32_1(Filter *f)
|
||||
{
|
||||
ADD32(f, 1)
|
||||
}
|
||||
static int u_sub32_1(Filter *f) { ADD32(f, 1) }
|
||||
|
||||
static int u_sub32_2(Filter *f)
|
||||
{
|
||||
ADD32(f, 2)
|
||||
}
|
||||
static int u_sub32_2(Filter *f) { ADD32(f, 2) }
|
||||
|
||||
static int u_sub32_3(Filter *f)
|
||||
{
|
||||
ADD32(f, 3)
|
||||
}
|
||||
|
||||
static int u_sub32_4(Filter *f)
|
||||
{
|
||||
ADD32(f, 4)
|
||||
}
|
||||
static int u_sub32_3(Filter *f) { ADD32(f, 3) }
|
||||
|
||||
static int u_sub32_4(Filter *f) { ADD32(f, 4) }
|
||||
|
||||
// scan
|
||||
static int s_sub32_1(Filter *f)
|
||||
{
|
||||
SCAN32(f, 1)
|
||||
}
|
||||
static int s_sub32_1(Filter *f) { SCAN32(f, 1) }
|
||||
|
||||
static int s_sub32_2(Filter *f)
|
||||
{
|
||||
SCAN32(f, 2)
|
||||
}
|
||||
static int s_sub32_2(Filter *f) { SCAN32(f, 2) }
|
||||
|
||||
static int s_sub32_3(Filter *f)
|
||||
{
|
||||
SCAN32(f, 3)
|
||||
}
|
||||
|
||||
static int s_sub32_4(Filter *f)
|
||||
{
|
||||
SCAN32(f, 4)
|
||||
}
|
||||
static int s_sub32_3(Filter *f) { SCAN32(f, 3) }
|
||||
|
||||
static int s_sub32_4(Filter *f) { SCAN32(f, 4) }
|
||||
|
||||
#undef SUB
|
||||
#undef ADD
|
||||
|
||||
@ -25,88 +25,46 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#include "sub.hh"
|
||||
|
||||
#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 SCAN8(f, N) SCAN(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 SCAN8(f, N) SCAN(f, N, unsigned char, get_8, set_8)
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
// filter
|
||||
static int f_sub8_1(Filter *f)
|
||||
{
|
||||
SUB8(f, 1)
|
||||
}
|
||||
static int f_sub8_1(Filter *f) { SUB8(f, 1) }
|
||||
|
||||
static int f_sub8_2(Filter *f)
|
||||
{
|
||||
SUB8(f, 2)
|
||||
}
|
||||
static int f_sub8_2(Filter *f) { SUB8(f, 2) }
|
||||
|
||||
static int f_sub8_3(Filter *f)
|
||||
{
|
||||
SUB8(f, 3)
|
||||
}
|
||||
|
||||
static int f_sub8_4(Filter *f)
|
||||
{
|
||||
SUB8(f, 4)
|
||||
}
|
||||
static int f_sub8_3(Filter *f) { SUB8(f, 3) }
|
||||
|
||||
static int f_sub8_4(Filter *f) { SUB8(f, 4) }
|
||||
|
||||
// unfilter
|
||||
static int u_sub8_1(Filter *f)
|
||||
{
|
||||
ADD8(f, 1)
|
||||
}
|
||||
static int u_sub8_1(Filter *f) { ADD8(f, 1) }
|
||||
|
||||
static int u_sub8_2(Filter *f)
|
||||
{
|
||||
ADD8(f, 2)
|
||||
}
|
||||
static int u_sub8_2(Filter *f) { ADD8(f, 2) }
|
||||
|
||||
static int u_sub8_3(Filter *f)
|
||||
{
|
||||
ADD8(f, 3)
|
||||
}
|
||||
|
||||
static int u_sub8_4(Filter *f)
|
||||
{
|
||||
ADD8(f, 4)
|
||||
}
|
||||
static int u_sub8_3(Filter *f) { ADD8(f, 3) }
|
||||
|
||||
static int u_sub8_4(Filter *f) { ADD8(f, 4) }
|
||||
|
||||
// scan
|
||||
static int s_sub8_1(Filter *f)
|
||||
{
|
||||
SCAN8(f, 1)
|
||||
}
|
||||
static int s_sub8_1(Filter *f) { SCAN8(f, 1) }
|
||||
|
||||
static int s_sub8_2(Filter *f)
|
||||
{
|
||||
SCAN8(f, 2)
|
||||
}
|
||||
static int s_sub8_2(Filter *f) { SCAN8(f, 2) }
|
||||
|
||||
static int s_sub8_3(Filter *f)
|
||||
{
|
||||
SCAN8(f, 3)
|
||||
}
|
||||
|
||||
static int s_sub8_4(Filter *f)
|
||||
{
|
||||
SCAN8(f, 4)
|
||||
}
|
||||
static int s_sub8_3(Filter *f) { SCAN8(f, 3) }
|
||||
|
||||
static int s_sub8_4(Filter *f) { SCAN8(f, 4) }
|
||||
|
||||
#undef SUB
|
||||
#undef ADD
|
||||
|
||||
163
src/filter/sw.h
163
src/filter/sw.h
@ -25,158 +25,91 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// 16-bit swaptrick ("naive")
|
||||
**************************************************************************/
|
||||
|
||||
#define SW16(f, cond, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 3; \
|
||||
do { \
|
||||
if (cond) \
|
||||
{ \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b)); \
|
||||
f->calls++; \
|
||||
b += 2 - 1; \
|
||||
} \
|
||||
} while (++b < b_end); \
|
||||
if (f->lastcall) f->lastcall += 2; \
|
||||
#define SW16(f, cond, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 3; \
|
||||
do { \
|
||||
if (cond) { \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b)); \
|
||||
f->calls++; \
|
||||
b += 2 - 1; \
|
||||
} \
|
||||
} while (++b < b_end); \
|
||||
if (f->lastcall) \
|
||||
f->lastcall += 2; \
|
||||
return 0;
|
||||
|
||||
|
||||
// filter
|
||||
static int f_sw16_e8(Filter *f)
|
||||
{
|
||||
SW16(f, (*b == 0xe8), get_le16, set_be16)
|
||||
}
|
||||
static int f_sw16_e8(Filter *f) { SW16(f, (*b == 0xe8), get_le16, set_be16) }
|
||||
|
||||
static int f_sw16_e9(Filter *f)
|
||||
{
|
||||
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_e9(Filter *f) { 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) }
|
||||
|
||||
// unfilter
|
||||
static int u_sw16_e8(Filter *f)
|
||||
{
|
||||
SW16(f, (*b == 0xe8), get_be16, set_le16)
|
||||
}
|
||||
static int u_sw16_e8(Filter *f) { SW16(f, (*b == 0xe8), get_be16, set_le16) }
|
||||
|
||||
static int u_sw16_e9(Filter *f)
|
||||
{
|
||||
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_e9(Filter *f) { 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) }
|
||||
|
||||
// scan
|
||||
static int s_sw16_e8(Filter *f)
|
||||
{
|
||||
SW16(f, (*b == 0xe8), get_le16, set_dummy)
|
||||
}
|
||||
static int s_sw16_e8(Filter *f) { SW16(f, (*b == 0xe8), get_le16, set_dummy) }
|
||||
|
||||
static int s_sw16_e9(Filter *f)
|
||||
{
|
||||
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_e9(Filter *f) { 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) }
|
||||
|
||||
#undef SW16
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// 32-bit swaptrick ("naive")
|
||||
**************************************************************************/
|
||||
|
||||
#define SW32(f, cond, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 5; \
|
||||
do { \
|
||||
if (cond) \
|
||||
{ \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b)); \
|
||||
f->calls++; \
|
||||
b += 4 - 1; \
|
||||
} \
|
||||
} while (++b < b_end); \
|
||||
if (f->lastcall) f->lastcall += 4; \
|
||||
#define SW32(f, cond, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 5; \
|
||||
do { \
|
||||
if (cond) { \
|
||||
b += 1; \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b)); \
|
||||
f->calls++; \
|
||||
b += 4 - 1; \
|
||||
} \
|
||||
} while (++b < b_end); \
|
||||
if (f->lastcall) \
|
||||
f->lastcall += 4; \
|
||||
return 0;
|
||||
|
||||
|
||||
// filter
|
||||
static int f_sw32_e8(Filter *f)
|
||||
{
|
||||
SW32(f, (*b == 0xe8), get_le32, set_be32)
|
||||
}
|
||||
static int f_sw32_e8(Filter *f) { SW32(f, (*b == 0xe8), get_le32, set_be32) }
|
||||
|
||||
static int f_sw32_e9(Filter *f)
|
||||
{
|
||||
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_e9(Filter *f) { 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) }
|
||||
|
||||
// unfilter
|
||||
static int u_sw32_e8(Filter *f)
|
||||
{
|
||||
SW32(f, (*b == 0xe8), get_be32, set_le32)
|
||||
}
|
||||
static int u_sw32_e8(Filter *f) { SW32(f, (*b == 0xe8), get_be32, set_le32) }
|
||||
|
||||
static int u_sw32_e9(Filter *f)
|
||||
{
|
||||
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_e9(Filter *f) { 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) }
|
||||
|
||||
// scan
|
||||
static int s_sw32_e8(Filter *f)
|
||||
{
|
||||
SW32(f, (*b == 0xe8), get_le32, set_dummy)
|
||||
}
|
||||
static int s_sw32_e8(Filter *f) { SW32(f, (*b == 0xe8), get_le32, set_dummy) }
|
||||
|
||||
static int s_sw32_e9(Filter *f)
|
||||
{
|
||||
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_e9(Filter *f) { 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) }
|
||||
|
||||
#undef SW32
|
||||
|
||||
|
||||
119
src/packer_c.cpp
119
src/packer_c.cpp
@ -33,67 +33,74 @@
|
||||
// compression method util
|
||||
**************************************************************************/
|
||||
|
||||
/*static*/ bool Packer::isValidCompressionMethod(int method)
|
||||
{
|
||||
/*static*/ bool Packer::isValidCompressionMethod(int method) {
|
||||
if (M_IS_LZMA(method))
|
||||
return true;
|
||||
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
|
||||
{
|
||||
#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 };
|
||||
|
||||
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 (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)
|
||||
small = file_size <= 512*1024;
|
||||
small = file_size <= 512 * 1024;
|
||||
if (level == 1 || small)
|
||||
return m_nrv2b;
|
||||
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
|
||||
{
|
||||
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 };
|
||||
|
||||
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 (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)
|
||||
small = file_size <= 512*1024;
|
||||
small = file_size <= 512 * 1024;
|
||||
if (level == 1 || small)
|
||||
return m_nrv2b;
|
||||
return m_nrv2e;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// loader util
|
||||
**************************************************************************/
|
||||
|
||||
static bool callsManyTimes(int format) {
|
||||
// clang-format off
|
||||
return
|
||||
UPX_F_LINUX_ELF_i386 ==format
|
||||
|| UPX_F_LINUX_ELFI_i386 ==format
|
||||
@ -113,10 +120,11 @@ static bool callsManyTimes(int format) {
|
||||
|| UPX_F_MACH_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[] =
|
||||
"N2BSMA10,N2BDEC10,N2BSMA20,N2BDEC20,N2BSMA30,"
|
||||
"N2BDEC30,N2BSMA40,N2BSMA50,N2BDEC50,N2BSMA60,"
|
||||
@ -209,6 +217,7 @@ const char *Packer::getDecompressorSections() const
|
||||
"LZMA_ELF00,LZMA_DEC10,LZMA_DEC30";
|
||||
static const char lzma_elf_fast[] =
|
||||
"LZMA_ELF00,LZMA_DEC20,LZMA_DEC30";
|
||||
// clang-format on
|
||||
|
||||
unsigned const method = ph_forced_method(ph.method);
|
||||
if (method == M_NRV2B_LE32)
|
||||
@ -217,46 +226,39 @@ const char *Packer::getDecompressorSections() const
|
||||
return opt->small ? nrv2d_le32_small : nrv2d_le32_fast;
|
||||
if (method == M_NRV2E_LE32)
|
||||
return opt->small ? nrv2e_le32_small : nrv2e_le32_fast;
|
||||
// if (method == M_CL1B_LE32)
|
||||
// return opt->small ? cl1b_le32_small : cl1b_le32_fast;
|
||||
// if (method == M_CL1B_LE32)
|
||||
// return opt->small ? cl1b_le32_small : cl1b_le32_fast;
|
||||
if (M_IS_LZMA(method)) {
|
||||
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");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
unsigned Packer::getDecompressorWrkmemSize() const
|
||||
{
|
||||
unsigned Packer::getDecompressorWrkmemSize() const {
|
||||
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;
|
||||
// FIXME - this is for i386 only
|
||||
size = 8 + 4 + ALIGN_UP(2 * res->num_probs, 4u);
|
||||
size = ALIGN_UP(size, 16u);
|
||||
}
|
||||
assert((int)size >= 0);
|
||||
assert((int) size >= 0);
|
||||
return size;
|
||||
}
|
||||
|
||||
void Packer::defineDecompressorSymbols()
|
||||
{
|
||||
void Packer::defineDecompressorSymbols() {
|
||||
if (callsManyTimes(ph.format)) {
|
||||
// ELF calls the decompressor many times; the parameters change!
|
||||
return;
|
||||
}
|
||||
if (M_IS_LZMA(ph.method))
|
||||
{
|
||||
if (M_IS_LZMA(ph.method)) {
|
||||
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
|
||||
upx_uint32_t properties = // lc, lp, pb, dummy
|
||||
(res->lit_context_bits << 0) |
|
||||
(res->lit_pos_bits << 8) |
|
||||
(res->pos_bits << 16);
|
||||
(res->lit_context_bits << 0) | (res->lit_pos_bits << 8) | (res->pos_bits << 16);
|
||||
if (bele->isBE()) // big endian - bswap32
|
||||
properties = bswap32(properties);
|
||||
|
||||
@ -267,9 +269,8 @@ void Packer::defineDecompressorSymbols()
|
||||
unsigned stack = getDecompressorWrkmemSize();
|
||||
linker->defineSymbol("lzma_stack_adjust", 0u - stack);
|
||||
|
||||
if (ph.format == UPX_F_DOS_EXE)
|
||||
{
|
||||
linker->defineSymbol("lzma_properties_hi", properties >> 16); // pb
|
||||
if (ph.format == UPX_F_DOS_EXE) {
|
||||
linker->defineSymbol("lzma_properties_hi", properties >> 16); // pb
|
||||
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_segment", (ph.u_len & 0xf0000) >> 4);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#define UPX_VERSION_HEX 0x040200 /* 04.02.00 */
|
||||
#define UPX_VERSION_STRING "4.2.0"
|
||||
#define UPX_VERSION_STRING4 "4.20"
|
||||
#define UPX_VERSION_DATE "Sep 12th 2023"
|
||||
#define UPX_VERSION_DATE_ISO "2023-09-12"
|
||||
#define UPX_VERSION_YEAR "2023"
|
||||
#pragma once
|
||||
#define UPX_VERSION_HEX 0x040200 /* 04.02.00 */
|
||||
#define UPX_VERSION_STRING "4.2.0"
|
||||
#define UPX_VERSION_STRING4 "4.20"
|
||||
#define UPX_VERSION_DATE "Oct 5th 2023"
|
||||
#define UPX_VERSION_DATE_ISO "2023-10-05"
|
||||
#define UPX_VERSION_YEAR "2023"
|
||||
|
||||
@ -215,7 +215,7 @@ void do_one_file(const char *const iname, char *const oname) may_throw {
|
||||
if (opt->output_name) {
|
||||
strcpy(tname, opt->output_name);
|
||||
if ((opt->force_overwrite || opt->force >= 2) && !preserve_link)
|
||||
FileBase::unlink(tname, false);
|
||||
(void) FileBase::unlink_noexcept(tname);
|
||||
} else {
|
||||
if (st.st_nlink < 2)
|
||||
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;
|
||||
} else if (r == 0 && S_ISLNK(ost.st_mode)) {
|
||||
// output_name is a symlink (valid or dangling)
|
||||
FileBase::unlink(tname, false);
|
||||
(void) FileBase::unlink_noexcept(tname);
|
||||
preserve_link = false; // not needed
|
||||
} else {
|
||||
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 {
|
||||
if (oname && oname[0]) {
|
||||
FileBase::unlink(oname, false);
|
||||
(void) FileBase::unlink_noexcept(oname);
|
||||
oname[0] = 0; // done with oname
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user