diff --git a/.appveyor.yml b/.appveyor.yml index 1d201971..c725d787 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -19,7 +19,7 @@ environment: init: - git config --global core.autocrlf input - - where bash & where cat & where curl & where git & where sed & where tar + - where bash & where cat & where curl & where git & where gzip & where readlink & where sed & where sha256sum & where tar # - bash --version & git --version & sed --version & tar --version - git --version & bash --version # - dir "c:\Program Files\Git\usr\bin" diff --git a/NEWS b/NEWS index 5df8b3f5..f5ed40b2 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,7 @@ User visible changes for UPX ================================================================== -Changes in 3.92 (XX XXX 2016): +Changes in 3.92 (27 Nov 2016): * UPX has moved to GitHub - the new home page is https://upx.github.io * All pe formats: important internal changes - reunited the diverged source files - please report regressions into the bug tracker. diff --git a/src/Makefile b/src/Makefile index 29b92e36..2317b8a7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -162,7 +162,7 @@ endif # automatically format some C++ source code files ifeq ($(shell uname),Linux) -CLANG_FORMAT_FILES += packhead.cpp +CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp CLANG_FORMAT_FILES += s_djgpp2.cpp s_object.cpp s_vcsa.cpp s_win32.cpp screen.h CLANG_FORMAT_FILES += snprintf.cpp CLANG_FORMAT_FILES += stdcxx.cpp stdcxx.h diff --git a/src/compress_lzma.cpp b/src/compress_lzma.cpp index 7fd1bef9..6e7f43ea 100644 --- a/src/compress_lzma.cpp +++ b/src/compress_lzma.cpp @@ -31,10 +31,13 @@ #include "mem.h" #if (ACC_CC_MSC) -# pragma warning(disable: 4456) // -Wno-shadow +# pragma warning(disable: 4456) // -Wno-shadow #endif #if (ACC_CC_MSC && (_MSC_VER < 1900)) -# pragma warning(disable: 4127) // warning C4127: conditional expression is constant +# pragma warning(disable: 4127) // warning C4127: conditional expression is constant +#endif +#if (ACC_CC_INTELC_GNUC) +# pragma warning(error: 424) // #424: extra ";" ignored #endif @@ -54,15 +57,6 @@ void lzma_compress_config_t::reset() } -#if !(WITH_LZMA) -extern int compress_lzma_dummy; -int compress_lzma_dummy = 0; -#else -#define opt compress_lzma_opt - -#undef USE_LZMA_PROPERTIES - - // INFO: the LZMA SDK is covered by a permissive license which allows // using unmodified LZMA source code in UPX and the UPX stubs. // See SPECIAL EXCEPTION below. @@ -100,28 +94,6 @@ int compress_lzma_dummy = 0; // while you keep LZMA SDK code unmodified. -#if (WITH_LZMA >= 0x461) -#include "C/7zVersion.h" -#if (WITH_LZMA != ((0x1000 * (MY_VER_MAJOR / 10)) + (0x0100 * (MY_VER_MAJOR % 10)) +\ - (0x0010 * (MY_VER_MINOR / 10)) + (0x0001 * (MY_VER_MINOR % 10)))) -# error "WITH_LZMA version mismatch" -#endif - -#if (WITH_LZMA >= 0x938) -#include "C/7zTypes.h" -#else -#include "C/Types.h" -#endif - -static void *cb_alloc(void *, size_t size) { - return malloc(size); -} -static void cb_free(void *, void *ptr) { - free(ptr); -} -#endif - - /************************************************************************* // compress defaults **************************************************************************/ @@ -138,13 +110,12 @@ static int prepare(lzma_compress_result_t *res, res->fast_mode = 2; res->num_fast_bytes = 64; // 5 .. 273 res->match_finder_cycles = 0; -#if 1 + // UPX overrides res->pos_bits = lzma_compress_config_t::pos_bits_t::default_value_c; res->lit_pos_bits = lzma_compress_config_t::lit_pos_bits_t::default_value_c; res->lit_context_bits = lzma_compress_config_t::lit_context_bits_t::default_value_c; res->dict_size = lzma_compress_config_t::dict_size_t::default_value_c; res->num_fast_bytes = lzma_compress_config_t::num_fast_bytes_t::default_value_c; -#endif // method overrides if (method >= 0x100) { res->pos_bits = (method >> 16) & 15; @@ -159,7 +130,7 @@ static int prepare(lzma_compress_result_t *res, res->lit_context_bits = 8; #endif - // FIXME: tune these settings according to level + // TODO: tune these settings according to level switch (level) { case 1: @@ -239,129 +210,19 @@ error: } -/************************************************************************* -// compress -**************************************************************************/ - -#if (WITH_LZMA >= 0x461) -#define _7ZIP_ST 1 -#define kLiteralNextStates kLiteralNextStates_enc -#include "C/LzmaEnc.h" -#include "C/LzmaEnc.c" -#include "C/LzFind.c" -#undef kLiteralNextStates -#undef kNumFullDistances - - -struct upx_ICompressProgress { - SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); - upx_callback_p cb; -}; - -static SRes cb_progress(void *p, UInt64 inSize, UInt64 outSize) { - upx_callback_p cb = ((upx_ICompressProgress *) p)->cb; - if (cb && cb->nprogress) - cb->nprogress(cb, (unsigned) inSize, (unsigned) outSize); - return SZ_OK; -} - - -int upx_lzma_compress ( const upx_bytep src, unsigned src_len, - upx_bytep dst, unsigned* dst_len, - upx_callback_p cb, - int method, int level, - const upx_compress_config_t *cconf_parm, - upx_compress_result_t *cresult ) -{ - assert(M_IS_LZMA(method)); - assert(level > 0); assert(cresult != NULL); - COMPILE_TIME_ASSERT(LZMA_PROPS_SIZE == 5) - - int r = UPX_E_ERROR; - int rh; - - unsigned dst_avail = *dst_len; - *dst_len = 0; - - ISzAlloc cba; cba.Alloc = cb_alloc; cba.Free = cb_free; - upx_ICompressProgress progress; - progress.Progress = cb_progress; progress.cb = cb; - - const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : NULL; - lzma_compress_result_t *res = &cresult->result_lzma; - if (prepare(res, src_len, method, level, lcconf) != 0) - goto error; - - CLzmaEncProps props; memset(&props, 0, sizeof(props)); - props.level = level; - LzmaEncProps_Init(&props); - props.pb = res->pos_bits; - props.lp = res->lit_pos_bits; - props.lc = res->lit_context_bits; - props.dictSize = res->dict_size; - props.algo = res->fast_mode ? 1 : 0; - props.fb = res->num_fast_bytes; - props.mc = res->match_finder_cycles; - - unsigned char props_buf[LZMA_PROPS_SIZE]; - SizeT props_buf_size; props_buf_size = LZMA_PROPS_SIZE; - -#if (USE_LZMA_PROPERTIES) - if (dst_avail < 1) - goto error; - dst[0] = 0; // filled below - dst += 1; *dst_len += 1; dst_avail -= 1; -#else - if (dst_avail < 2) - goto error; - // extra stuff in first byte: 5 high bits convenience for stub decompressor - unsigned tt; tt = res->lit_context_bits + res->lit_pos_bits; - dst[0] = ((tt << 3) | res->pos_bits); - dst[1] = ((res->lit_pos_bits << 4) | (res->lit_context_bits)); - dst += 2; *dst_len += 2; dst_avail -= 2; -#endif - SizeT x_len; x_len = dst_avail; - rh = LzmaEncode(dst, &x_len, src, src_len, - &props, props_buf, &props_buf_size, 0, - (ICompressProgress *) (void *) &progress, &cba, &cba); - assert(x_len <= dst_avail); - *dst_len += x_len; - if (rh == SZ_OK) { -#if (USE_LZMA_PROPERTIES) - dst[-1] = props_buf[0]; -#endif - r = UPX_E_OK; - } - -error: - //printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len); - return r; -} - -#endif /* (WITH_LZMA >= 0x461) */ - - /************************************************************************* // compress - cruft because of pseudo-COM layer **************************************************************************/ -#if (WITH_LZMA < 0x461) - #undef MSDOS #undef OS2 #undef _WIN32 #undef _WIN32_WCE #undef COMPRESS_MF_MT #undef _NO_EXCEPTIONS -#if (WITH_LZMA >= 0x449) -# define INITGUID 1 -//# include "CPP/7zip/Compress/LZMA/LZMADecoder.h" -# include "CPP/7zip/Compress/LZMA/LZMAEncoder.h" -#else -# include "C/Common/MyInitGuid.h" -//# include "C/7zip/Compress/LZMA/LZMADecoder.h" -# include "C/7zip/Compress/LZMA/LZMAEncoder.h" -#endif +#include "C/Common/MyInitGuid.h" +//#include "C/7zip/Compress/LZMA/LZMADecoder.h" +#include "C/7zip/Compress/LZMA/LZMAEncoder.h" namespace MyLzma { @@ -380,7 +241,7 @@ STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize) { size_t remain = b_size - b_pos; if (size > remain) size = (UInt32) remain; - memcpy(data, b_buf + b_pos, size); + memmove(data, b_buf + b_pos, size); b_pos += size; if (processedSize != NULL) *processedSize = size; return S_OK; @@ -406,7 +267,7 @@ STDMETHODIMP OutStream::Write(const void *data, UInt32 size, UInt32 *processedSi { size_t remain = b_size - b_pos; if (size > remain) size = (UInt32) remain, overflow = true; - memcpy(b_buf + b_pos, data, size); + memmove(b_buf + b_pos, data, size); b_pos += size; if (processedSize != NULL) *processedSize = size; return overflow ? E_FAIL : S_OK; @@ -429,35 +290,16 @@ STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outS } // namespace - -#if (ACC_CC_INTELC_GNUC) -//# pragma warning(disable: 424) // #424: extra ";" ignored -# pragma warning(error: 424) // #424: extra ";" ignored -#endif - -#if (WITH_LZMA >= 0x449) -# include "C/Alloc.c" -# include "C/7zCrc.c" -# include "C/Compress/Lz/MatchFinder.c" -//# include "CPP/7zip/Common/InBuffer.cpp" -# include "CPP/7zip/Common/OutBuffer.cpp" -# include "CPP/7zip/Common/StreamUtils.cpp" -//# include "CPP/7zip/Compress/LZ/LZOutWindow.cpp" -//# include "CPP/7zip/Compress/LZMA/LZMADecoder.cpp" -# include "CPP/7zip/Compress/LZMA/LZMAEncoder.cpp" -# include "CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp" -#else -# include "C/Common/Alloc.cpp" -# include "C/Common/CRC.cpp" -//# include "C/7zip/Common/InBuffer.cpp" -# include "C/7zip/Common/OutBuffer.cpp" -# include "C/7zip/Common/StreamUtils.cpp" -# include "C/7zip/Compress/LZ/LZInWindow.cpp" -//# include "C/7zip/Compress/LZ/LZOutWindow.cpp" -//# include "C/7zip/Compress/LZMA/LZMADecoder.cpp" -# include "C/7zip/Compress/LZMA/LZMAEncoder.cpp" -# include "C/7zip/Compress/RangeCoder/RangeCoderBit.cpp" -#endif +#include "C/Common/Alloc.cpp" +#include "C/Common/CRC.cpp" +//#include "C/7zip/Common/InBuffer.cpp" +#include "C/7zip/Common/OutBuffer.cpp" +#include "C/7zip/Common/StreamUtils.cpp" +#include "C/7zip/Compress/LZ/LZInWindow.cpp" +//#include "C/7zip/Compress/LZ/LZOutWindow.cpp" +//#include "C/7zip/Compress/LZMA/LZMADecoder.cpp" +#include "C/7zip/Compress/LZMA/LZMAEncoder.cpp" +#include "C/7zip/Compress/RangeCoder/RangeCoderBit.cpp" #undef RC_NORMALIZE @@ -496,14 +338,10 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len, NCoderPropID::kMatchFinder // 7 mf }; PROPVARIANT pr[8]; -#ifdef COMPRESS_MF_BT4 const unsigned nprops = 8; static wchar_t matchfinder[] = L"BT4"; assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0); pr[7].vt = VT_BSTR; pr[7].bstrVal = matchfinder; -#else - const unsigned nprops = 7; -#endif pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = VT_UI4; pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4; if (prepare(res, src_len, method, level, lcconf) != 0) @@ -516,11 +354,7 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len, pr[5].uintVal = res->num_fast_bytes; pr[6].uintVal = res->match_finder_cycles; -#ifndef _NO_EXCEPTIONS try { -#else -# error -#endif if (enc.SetCoderProperties(propIDs, pr, nprops) != S_OK) goto error; @@ -532,21 +366,17 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len, goto error; } assert(os.b_pos == 5); -#if (USE_LZMA_PROPERTIES) - os.b_pos = 1; -#else os.b_pos = 0; // extra stuff in first byte: 5 high bits convenience for stub decompressor unsigned t = res->lit_context_bits + res->lit_pos_bits; os.WriteByte(Byte((t << 3) | res->pos_bits)); os.WriteByte(Byte((res->lit_pos_bits << 4) | (res->lit_context_bits))); -#endif rh = enc.Code(&is, &os, NULL, NULL, &progress); -#ifndef _NO_EXCEPTIONS - } catch (...) { rh = E_OUTOFMEMORY; } -#endif + } catch (...) { + rh = E_OUTOFMEMORY; + } assert(is.b_pos <= src_len); assert(os.b_pos <= *dst_len); @@ -571,121 +401,17 @@ error: return r; } -#endif /* (WITH_LZMA < 0x461) */ - /************************************************************************* // decompress **************************************************************************/ -#if (WITH_LZMA >= 0x461) - -#undef _LZMA_PROB32 -#include "C/LzmaDec.h" -#include "C/LzmaDec.c" - - -int upx_lzma_decompress ( const upx_bytep src, unsigned src_len, - upx_bytep dst, unsigned* dst_len, - int method, - const upx_compress_result_t *cresult ) -{ -#define Properties prop - assert(M_IS_LZMA(method)); - // see res->num_probs above - COMPILE_TIME_ASSERT(sizeof(CLzmaProb) == 2) - COMPILE_TIME_ASSERT(LZMA_PROPS_SIZE == 5) - COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846) - COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768) - - ISzAlloc cba; cba.Alloc = cb_alloc; cba.Free = cb_free; - CLzmaDec s; memset(&s, 0, sizeof(s)); - SizeT srcLen = 0; - int r = UPX_E_ERROR; - SRes rh; - ELzmaStatus status; - -#if (USE_LZMA_PROPERTIES) - rh = LzmaProps_Decode(&s.Properties, src, src_len); - if (rh != 0) - goto error; - src += 1; src_len -= 1; -#else - if (src_len < 3) - goto error; - s.Properties.pb = src[0] & 7; - s.Properties.lp = (src[1] >> 4); - s.Properties.lc = src[1] & 15; - if (s.Properties.pb >= 5) goto error; - if (s.Properties.lp >= 5) goto error; - if (s.Properties.lc >= 9) goto error; - // extra - if ((src[0] >> 3) != (int)(s.Properties.lc + s.Properties.lp)) goto error; - src += 2; src_len -= 2; -#endif - s.Properties.dicSize = 0; - - if (cresult) - { - assert(cresult->method == method); - assert(cresult->result_lzma.pos_bits == (unsigned) s.Properties.pb); - assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp); - assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc); - assert(cresult->result_lzma.num_probs == (unsigned) LzmaProps_GetNumProbs(&s.Properties)); - const lzma_compress_result_t *res = &cresult->result_lzma; - UNUSED(res); - //printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs); - } - - rh = LzmaDec_AllocateProbs2(&s, &s.Properties, &cba); - if (rh != SZ_OK) - { - r = UPX_E_OUT_OF_MEMORY; - goto error; - } - - s.dic = dst; s.dicPos = 0; s.dicBufSize = *dst_len; - LzmaDec_Init(&s); - srcLen = src_len; - rh = LzmaDec_DecodeToDic(&s, *dst_len, src, &srcLen, LZMA_FINISH_ANY, &status); - assert(srcLen <= src_len); - assert(s.dicPos <= *dst_len); - if (rh == SZ_OK && status == LZMA_STATUS_NEEDS_MORE_INPUT) - rh = SZ_ERROR_INPUT_EOF; - if (rh == SZ_OK && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) - { - r = UPX_E_OK; - if (srcLen != src_len) - r = UPX_E_INPUT_NOT_CONSUMED; - } -error: - *dst_len = s.dicPos; - LzmaDec_FreeProbs(&s, &cba); - return r; -#undef Properties -} - - -#endif /* (WITH_LZMA >= 0x461) */ - - -/************************************************************************* -// decompress -**************************************************************************/ - -#if (WITH_LZMA < 0x461) - #undef _LZMA_IN_CB #undef _LZMA_OUT_READ #undef _LZMA_PROB32 #undef _LZMA_LOC_OPT -#if (WITH_LZMA >= 0x449) -# include "C/Compress/Lzma/LzmaDecode.h" -# include "C/Compress/Lzma/LzmaDecode.c" -#else -# include "C/7zip/Compress/LZMA_C/LzmaDecode.h" -# include "C/7zip/Compress/LZMA_C/LzmaDecode.c" -#endif +#include "C/7zip/Compress/LZMA_C/LzmaDecode.h" +#include "C/7zip/Compress/LZMA_C/LzmaDecode.c" int upx_lzma_decompress ( const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned* dst_len, @@ -703,14 +429,6 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len, int r = UPX_E_ERROR; int rh; -#if (USE_LZMA_PROPERTIES) - if (src_len < 2) - goto error; - rh = LzmaDecodeProperties(&s.Properties, src, src_len); - if (rh != 0) - goto error; - src += 1; src_len -= 1; -#else if (src_len < 3) goto error; s.Properties.pb = src[0] & 7; @@ -722,7 +440,6 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len, // extra if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp) goto error; src += 2; src_len -= 2; -#endif if (cresult) { @@ -757,8 +474,6 @@ error: return r; } -#endif /* (WITH_LZMA < 0x461) */ - /************************************************************************* // test_overlap - see for semantics @@ -801,16 +516,7 @@ int upx_lzma_init(void) const char *upx_lzma_version_string(void) { -#if (WITH_LZMA >= 0x461) -# error "invalid WITH_LZMA version" - return MY_VERSION; -#elif (WITH_LZMA + 0 == 0x457) -# error "invalid WITH_LZMA version" - return "4.57"; -#elif (WITH_LZMA + 0 == 0x449) -# error "invalid WITH_LZMA version" - return "4.49"; -#elif (WITH_LZMA + 0 == 0x443) +#if (WITH_LZMA == 0x443) return "4.43"; #else # error "unknown WITH_LZMA version" @@ -819,6 +525,4 @@ const char *upx_lzma_version_string(void) } -#endif /* WITH_LZMA */ - /* vim:set ts=4 sw=4 et: */ diff --git a/src/conf.h b/src/conf.h index 4c852e58..1b146dff 100644 --- a/src/conf.h +++ b/src/conf.h @@ -55,8 +55,13 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4) ACC_COMPILE_TIME_ASSERT_HEADER((1u << 31) << 1 == 0) ACC_COMPILE_TIME_ASSERT_HEADER(((int)(1u << 31)) >> 31 == -1) // arithmetic right shift +ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 255) // -funsigned-char ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) > 0) // -funsigned-char +#if (ACC_CC_MSC) +# pragma warning(error: 4319) +#endif + // FIXME - quick hack for arm-wince-gcc-3.4 (Debian pocketpc-*.deb packages) #if 1 && (ACC_ARCH_ARM) && defined(__pe__) && !defined(__CEGCC__) && !defined(_WIN32) # undef HAVE_CHMOD diff --git a/src/linker.cpp b/src/linker.cpp index dbd7accc..b314517f 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -25,17 +25,12 @@ */ - #include "conf.h" #include "linker.h" -static unsigned hex(unsigned char c) -{ - return (c & 0xf) + (c > '9' ? 9 : 0); -} +static unsigned hex(unsigned char c) { return (c & 0xf) + (c > '9' ? 9 : 0); } -static bool update_capacity(unsigned size, unsigned *capacity) -{ +static bool update_capacity(unsigned size, unsigned *capacity) { if (size < *capacity) return false; if (*capacity == 0) @@ -45,8 +40,7 @@ static bool update_capacity(unsigned size, unsigned *capacity) return true; } -static void __acc_cdecl_va internal_error(const char *format, ...) -{ +static void __acc_cdecl_va internal_error(const char *format, ...) { static char buf[1024]; va_list ap; @@ -57,79 +51,62 @@ static void __acc_cdecl_va internal_error(const char *format, ...) throwInternalError(buf); } - /************************************************************************* // Section **************************************************************************/ -ElfLinker::Section::Section(const char *n, const void *i, unsigned s, unsigned a) : - name(NULL), output(NULL), size(s), offset(0), p2align(a), next(NULL) -{ +ElfLinker::Section::Section(const char *n, const void *i, unsigned s, unsigned a) + : name(NULL), output(NULL), size(s), offset(0), p2align(a), next(NULL) { name = strdup(n); assert(name != NULL); input = malloc(s + 1); assert(input != NULL); if (s != 0) memcpy(input, i, s); - ((char *)input)[s] = 0; + ((char *) input)[s] = 0; } -ElfLinker::Section::~Section() -{ +ElfLinker::Section::~Section() { free(name); free(input); } - /************************************************************************* // Symbol **************************************************************************/ -ElfLinker::Symbol::Symbol(const char *n, Section *s, upx_uint64_t o) : - name(NULL), section(s), offset(o) -{ +ElfLinker::Symbol::Symbol(const char *n, Section *s, upx_uint64_t o) + : name(NULL), section(s), offset(o) { name = strdup(n); assert(name != NULL); assert(section != NULL); } -ElfLinker::Symbol::~Symbol() -{ - free(name); -} - +ElfLinker::Symbol::~Symbol() { free(name); } /************************************************************************* // Relocation **************************************************************************/ -ElfLinker::Relocation::Relocation(const Section *s, unsigned o, const char *t, - const Symbol *v, upx_uint64_t a) : - section(s), offset(o), type(t), value(v), add(a) -{ +ElfLinker::Relocation::Relocation(const Section *s, unsigned o, const char *t, const Symbol *v, + upx_uint64_t a) + : section(s), offset(o), type(t), value(v), add(a) { assert(section != NULL); } - /************************************************************************* // ElfLinker **************************************************************************/ -ElfLinker::ElfLinker() : - bele(&N_BELE_RTP::le_policy), - input(NULL), output(NULL), head(NULL), tail(NULL), - sections(NULL), symbols(NULL), relocations(NULL), - nsections(0), nsections_capacity(0), - nsymbols(0), nsymbols_capacity(0), - nrelocations(0), nrelocations_capacity(0), - reloc_done(false) -{ -} +ElfLinker::ElfLinker() + : bele(&N_BELE_RTP::le_policy), input(NULL), output(NULL), head(NULL), tail(NULL), + sections(NULL), symbols(NULL), relocations(NULL), nsections(0), nsections_capacity(0), + nsymbols(0), nsymbols_capacity(0), nrelocations(0), nrelocations_capacity(0), + reloc_done(false) {} -ElfLinker::~ElfLinker() -{ - delete [] input; - delete [] output; +ElfLinker::~ElfLinker() { + delete[] input; + delete[] output; unsigned ic; for (ic = 0; ic < nsections; ic++) @@ -143,24 +120,19 @@ ElfLinker::~ElfLinker() free(relocations); } -void ElfLinker::init(const void *pdata_v, int plen) -{ +void ElfLinker::init(const void *pdata_v, int plen) { const upx_byte *pdata = (const upx_byte *) pdata_v; - if (plen >= 16 && memcmp(pdata, "UPX#", 4) == 0) - { + if (plen >= 16 && memcmp(pdata, "UPX#", 4) == 0) { // decompress pre-compressed stub-loader int method; unsigned u_len, c_len; - if (pdata[4]) - { + if (pdata[4]) { method = pdata[4]; u_len = get_le16(pdata + 5); c_len = get_le16(pdata + 7); pdata += 9; assert(9 + c_len == (unsigned) plen); - } - else - { + } else { method = pdata[5]; u_len = get_le32(pdata + 6); c_len = get_le32(pdata + 10); @@ -176,9 +148,7 @@ void ElfLinker::init(const void *pdata_v, int plen) throwOutOfMemoryException(); if (r != UPX_E_OK || new_len != u_len) throwBadLoader(); - } - else - { + } else { inputlen = plen; input = new upx_byte[inputlen + 1]; if (inputlen) @@ -189,7 +159,9 @@ void ElfLinker::init(const void *pdata_v, int plen) output = new upx_byte[inputlen ? inputlen : 0x4000]; outputlen = 0; - if ((int)strlen("Sections:\n" "SYMBOL TABLE:\n" "RELOCATION RECORDS FOR ") < inputlen) { + if ((int) strlen("Sections:\n" + "SYMBOL TABLE:\n" + "RELOCATION RECORDS FOR ") < inputlen) { int pos = find(input, inputlen, "Sections:\n", 10); assert(pos != -1); char *psections = (char *) input + pos; @@ -202,53 +174,45 @@ void ElfLinker::init(const void *pdata_v, int plen) preprocessSections(psections, psymbols); preprocessSymbols(psymbols, prelocs); - preprocessRelocations(prelocs, (char*) input + inputlen); + preprocessRelocations(prelocs, (char *) input + inputlen); addLoader("*UND*"); } } -void ElfLinker::preprocessSections(char *start, char const *end) -{ +void ElfLinker::preprocessSections(char *start, char *end) { char *nextl; - for (nsections = 0; start < end; start = 1+ nextl) - { + for (nsections = 0; start < end; start = 1 + nextl) { nextl = strchr(start, '\n'); assert(nextl != NULL); - *nextl = '\0'; // a record is a line + *nextl = '\0'; // a record is a line unsigned offset, size, align; char name[1024]; - if (sscanf(start, "%*d %1023s %x %*d %*d %x 2**%d", - name, &size, &offset, &align) == 4) - { + if (sscanf(start, "%*d %1023s %x %*d %*d %x 2**%d", name, &size, &offset, &align) == 4) { char *n = strstr(start, name); n[strlen(name)] = 0; addSection(n, input + offset, size, align); - //printf("section %s preprocessed\n", n); + // printf("section %s preprocessed\n", n); } } addSection("*ABS*", NULL, 0, 0); addSection("*UND*", NULL, 0, 0); } -void ElfLinker::preprocessSymbols(char *start, char const *end) -{ +void ElfLinker::preprocessSymbols(char *start, char *end) { char *nextl; - for (nsymbols = 0; start < end; start = 1+ nextl) - { + for (nsymbols = 0; start < end; start = 1 + nextl) { nextl = strchr(start, '\n'); assert(nextl != NULL); - *nextl = '\0'; // a record is a line + *nextl = '\0'; // a record is a line unsigned value, offset; char section[1024]; char symbol[1024]; - if (sscanf(start, "%x g *ABS* %x %1023s", - &value, &offset, symbol) == 3) - { + if (sscanf(start, "%x g *ABS* %x %1023s", &value, &offset, symbol) == 3) { char *s = strstr(start, symbol); s[strlen(symbol)] = 0; addSymbol(s, "*ABS*", value); @@ -263,25 +227,23 @@ void ElfLinker::preprocessSymbols(char *start, char const *end) #endif &offset, section, symbol) == 3) { - char *s = strstr(start, symbol); - s[strlen(symbol)] = 0; - if (strcmp(section, "*UND*") == 0) - offset = 0xdeaddead; - assert(strcmp(section, "*ABS*") != 0); - addSymbol(s, section, offset); - } + char *s = strstr(start, symbol); + s[strlen(symbol)] = 0; + if (strcmp(section, "*UND*") == 0) + offset = 0xdeaddead; + assert(strcmp(section, "*ABS*") != 0); + addSymbol(s, section, offset); + } } } -void ElfLinker::preprocessRelocations(char *start, char const *end) -{ +void ElfLinker::preprocessRelocations(char *start, char *end) { Section *section = NULL; char *nextl; - for (nrelocations = 0; start < end; start = 1+ nextl) - { + for (nrelocations = 0; start < end; start = 1 + nextl) { nextl = strchr(start, '\n'); assert(nextl != NULL); - *nextl = '\0'; // a record is a line + *nextl = '\0'; // a record is a line { char sect[1024]; @@ -293,9 +255,7 @@ void ElfLinker::preprocessRelocations(char *start, char const *end) char type[100]; char symbol[1024]; - if (sscanf(start, "%x %99s %1023s", - &offset, type, symbol) == 3) - { + if (sscanf(start, "%x %99s %1023s", &offset, type, symbol) == 3) { char *t = strstr(start, type); t[strlen(type)] = 0; @@ -303,16 +263,15 @@ void ElfLinker::preprocessRelocations(char *start, char const *end) char *p = strstr(symbol, "+0x"); if (p == NULL) p = strstr(symbol, "-0x"); - if (p) - { + if (p) { char sign = *p; - *p = 0; // terminate the symbol name + *p = 0; // terminate the symbol name p += 3; assert(strlen(p) == 8 || strlen(p) == 16); #if (ACC_CC_MSC && (_MSC_VER < 1800)) unsigned a = 0, b = 0; if (sscanf(p, "%08x%08x", &a, &b) == 2) - add = ((upx_uint64_t)a << 32) | b; + add = ((upx_uint64_t) a << 32) | b; else add = a; #else @@ -326,14 +285,14 @@ void ElfLinker::preprocessRelocations(char *start, char const *end) if (section) { addRelocation(section->name, offset, t, symbol, add); - //printf("relocation %s %s %x %llu preprocessed\n", section->name, symbol, offset, (unsigned long long) add); + // printf("relocation %s %s %x %llu preprocessed\n", section->name, symbol, offset, + // (unsigned long long) add); } } } } -ElfLinker::Section *ElfLinker::findSection(const char *name, bool fatal) const -{ +ElfLinker::Section *ElfLinker::findSection(const char *name, bool fatal) const { for (unsigned ic = 0; ic < nsections; ic++) if (strcmp(sections[ic]->name, name) == 0) return sections[ic]; @@ -342,8 +301,7 @@ ElfLinker::Section *ElfLinker::findSection(const char *name, bool fatal) const return NULL; } -ElfLinker::Symbol *ElfLinker::findSymbol(const char *name, bool fatal) const -{ +ElfLinker::Symbol *ElfLinker::findSymbol(const char *name, bool fatal) const { for (unsigned ic = 0; ic < nsymbols; ic++) if (strcmp(symbols[ic]->name, name) == 0) return symbols[ic]; @@ -352,13 +310,16 @@ ElfLinker::Symbol *ElfLinker::findSymbol(const char *name, bool fatal) const return NULL; } -ElfLinker::Section *ElfLinker::addSection(const char *sname, const void *sdata, int slen, unsigned p2align) -{ - //printf("addSection: %s len=%d align=%d\n", sname, slen, p2align); +ElfLinker::Section *ElfLinker::addSection(const char *sname, const void *sdata, int slen, + unsigned p2align) { + // printf("addSection: %s len=%d align=%d\n", sname, slen, p2align); if (update_capacity(nsections, &nsections_capacity)) - sections = static_cast
(realloc(sections, nsections_capacity * sizeof(Section *))); + sections = + static_cast
(realloc(sections, nsections_capacity * sizeof(Section *))); assert(sections); - assert(sname); assert(sname[0]); assert(sname[strlen(sname)-1] != ':'); + assert(sname); + assert(sname[0]); + assert(sname[strlen(sname) - 1] != ':'); assert(findSection(sname, false) == NULL); Section *sec = new Section(sname, sdata, slen, p2align); sections[nsections++] = sec; @@ -366,28 +327,27 @@ ElfLinker::Section *ElfLinker::addSection(const char *sname, const void *sdata, } ElfLinker::Symbol *ElfLinker::addSymbol(const char *name, const char *section, - upx_uint64_t offset) -{ - //printf("addSymbol: %s %s 0x%x\n", name, section, offset); + upx_uint64_t offset) { + // printf("addSymbol: %s %s 0x%x\n", name, section, offset); if (update_capacity(nsymbols, &nsymbols_capacity)) symbols = static_cast(realloc(symbols, nsymbols_capacity * sizeof(Symbol *))); assert(symbols != NULL); - assert(name); assert(name[0]); assert(name[strlen(name)-1] != ':'); + assert(name); + assert(name[0]); + assert(name[strlen(name) - 1] != ':'); assert(findSymbol(name, false) == NULL); Symbol *sym = new Symbol(name, findSection(section), offset); symbols[nsymbols++] = sym; return sym; } -ElfLinker::Relocation *ElfLinker::addRelocation(const char *section, unsigned off, - const char *type, const char *symbol, - upx_uint64_t add) -{ +ElfLinker::Relocation *ElfLinker::addRelocation(const char *section, unsigned off, const char *type, + const char *symbol, upx_uint64_t add) { if (update_capacity(nrelocations, &nrelocations_capacity)) - relocations = static_cast(realloc(relocations, (nrelocations_capacity) * sizeof(Relocation *))); + relocations = static_cast( + realloc(relocations, (nrelocations_capacity) * sizeof(Relocation *))); assert(relocations != NULL); - Relocation *rel = new Relocation(findSection(section), off, - type, findSymbol(symbol), add); + Relocation *rel = new Relocation(findSection(section), off, type, findSymbol(symbol), add); relocations[nrelocations++] = rel; return rel; } @@ -400,19 +360,16 @@ void ElfLinker::setLoaderAlignOffset(int phase) } #endif -int ElfLinker::addLoader(const char *sname) -{ +int ElfLinker::addLoader(const char *sname) { assert(sname != NULL); if (!sname[0]) return outputlen; char *begin = strdup(sname); char *end = begin + strlen(begin); - for (char *sect = begin; sect < end; ) - { + for (char *sect = begin; sect < end;) { for (char *tokend = sect; *tokend; tokend++) - if (*tokend == ' ' || *tokend == ',') - { + if (*tokend == ' ' || *tokend == ',') { *tokend = 0; break; } @@ -425,39 +382,34 @@ int ElfLinker::addLoader(const char *sname) if (m) { l %= hex(sect[1]); } - if (l) - { + if (l) { if (sect[3] == 'D') alignData(l); else alignCode(l); tail->size += l; } - } - else - { + } else { Section *section = findSection(sect); if (section->p2align) { assert(tail); assert(tail != section); // .p2align must be < 32 unsigned const v = ~0u << section->p2align; - if (unsigned const l = ~v & (0u-(unsigned)(tail->offset + tail->size))) { + if (unsigned const l = ~v & (0u - (unsigned) (tail->offset + tail->size))) { alignCode(l); tail->size += l; } } memcpy(output + outputlen, section->input, section->size); section->output = output + outputlen; - //printf("section added: 0x%04x %3d %s\n", outputlen, section->size, section->name); + // printf("section added: 0x%04x %3d %s\n", outputlen, section->size, section->name); outputlen += section->size; - if (head) - { + if (head) { tail->next = section; section->offset = tail->offset + tail->size; - } - else + } else head = section; tail = section; } @@ -467,80 +419,68 @@ int ElfLinker::addLoader(const char *sname) return outputlen; } -void ElfLinker::addLoader(const char *s, va_list ap) -{ - while (s != NULL) - { +void ElfLinker::addLoader(const char *s, va_list ap) { + while (s != NULL) { addLoader(s); s = va_arg(ap, const char *); } } -void __acc_cdecl_va ElfLinker::addLoaderVA(const char *s, ...) -{ +void __acc_cdecl_va ElfLinker::addLoaderVA(const char *s, ...) { va_list ap; va_start(ap, s); addLoader(s, ap); va_end(ap); } -int ElfLinker::getSection(const char *sname, int *slen) const -{ +int ElfLinker::getSection(const char *sname, int *slen) const { const Section *section = findSection(sname); if (slen) *slen = section->size; return (int) (section->output - output); } -int ElfLinker::getSectionSize(const char *sname) const -{ +int ElfLinker::getSectionSize(const char *sname) const { const Section *section = findSection(sname); return section->size; } -upx_byte *ElfLinker::getLoader(int *llen) const -{ +upx_byte *ElfLinker::getLoader(int *llen) const { if (llen) *llen = outputlen; return output; } -void ElfLinker::relocate() -{ +void ElfLinker::relocate() { assert(!reloc_done); reloc_done = true; - for (unsigned ic = 0; ic < nrelocations; ic++) - { + for (unsigned ic = 0; ic < nrelocations; ic++) { const Relocation *rel = relocations[ic]; upx_uint64_t value = 0; if (rel->section->output == NULL) continue; - if (strcmp(rel->value->section->name, "*ABS*") == 0) - { + if (strcmp(rel->value->section->name, "*ABS*") == 0) { value = rel->value->offset; - } - else if (strcmp(rel->value->section->name, "*UND*") == 0 && - rel->value->offset == 0xdeaddead) + } else if (strcmp(rel->value->section->name, "*UND*") == 0 && + rel->value->offset == 0xdeaddead) internal_error("undefined symbol '%s' referenced\n", rel->value->name); else if (rel->value->section->output == NULL) - internal_error("can not apply reloc '%s:%x' without section '%s'\n", - rel->section->name, rel->offset, - rel->value->section->name); - else - { - value = rel->value->section->offset + - rel->value->offset + rel->add; + internal_error("can not apply reloc '%s:%x' without section '%s'\n", rel->section->name, + rel->offset, rel->value->section->name); + else { + value = rel->value->section->offset + rel->value->offset + rel->add; } upx_byte *location = rel->section->output + rel->offset; - //printf("%-28s %-28s %-10s 0x%16llx 0x%16llx\n", rel->section->name, rel->value->name, rel->type, (long long) value, (long long) value - rel->section->offset - rel->offset); - //printf(" %llx %d %llx %d %llx : %d\n", (long long) value, rel->value->section->offset, rel->value->offset, rel->offset, (long long) rel->add, *location); + // printf("%-28s %-28s %-10s 0x%16llx 0x%16llx\n", rel->section->name, rel->value->name, + // rel->type, (long long) value, (long long) value - rel->section->offset - rel->offset); + // printf(" %llx %d %llx %d %llx : %d\n", (long long) value, rel->value->section->offset, + // rel->value->offset, rel->offset, (long long) rel->add, *location); relocate1(rel, location, value, rel->type); } } -void ElfLinker::defineSymbol(const char *name, upx_uint64_t value) -{ +void ElfLinker::defineSymbol(const char *name, upx_uint64_t value) { Symbol *symbol = findSymbol(name); if (strcmp(symbol->section->name, "*ABS*") == 0) internal_error("defineSymbol: symbol '%s' is *ABS*\n", name); @@ -548,77 +488,62 @@ void ElfLinker::defineSymbol(const char *name, upx_uint64_t value) symbol->offset = value; else if (strcmp(symbol->section->name, name) == 0) // for sections { - for (Section *section = symbol->section; section; section = section->next) - { + for (Section *section = symbol->section; section; section = section->next) { assert(section->offset < value); section->offset = value; value += section->size; } - } - else + } else internal_error("defineSymbol: symbol '%s' already defined\n", name); } // debugging support -void ElfLinker::dumpSymbol(const Symbol *symbol, unsigned flags, FILE *fp) const -{ +void ElfLinker::dumpSymbol(const Symbol *symbol, unsigned flags, FILE *fp) const { if ((flags & 1) && symbol->section->output == NULL) return; - char d0[16+1], d1[16+1]; + char d0[16 + 1], d1[16 + 1]; upx_snprintf(d0, sizeof(d0), "%016llx", (upx_uint64_t) symbol->offset); upx_snprintf(d1, sizeof(d1), "%016llx", (upx_uint64_t) symbol->section->offset); - fprintf(fp, "%-28s 0x%-16s | %-28s 0x%-16s\n", - symbol->name, d0, symbol->section->name, d1); + fprintf(fp, "%-28s 0x%-16s | %-28s 0x%-16s\n", symbol->name, d0, symbol->section->name, d1); } -void ElfLinker::dumpSymbols(unsigned flags, FILE *fp) const -{ +void ElfLinker::dumpSymbols(unsigned flags, FILE *fp) const { if (fp == NULL) fp = stdout; - if ((flags & 2) == 0) - { + if ((flags & 2) == 0) { // default: dump symbols in used section order - for (const Section *section = head; section; section = section->next) - { - char d1[16+1]; + for (const Section *section = head; section; section = section->next) { + char d1[16 + 1]; upx_snprintf(d1, sizeof(d1), "%016llx", (upx_uint64_t) section->offset); fprintf(fp, "%-42s%-28s 0x%-16s\n", "", section->name, d1); - for (unsigned ic = 0; ic < nsymbols; ic++) - { + for (unsigned ic = 0; ic < nsymbols; ic++) { const Symbol *symbol = symbols[ic]; if (symbol->section == section && strcmp(symbol->name, section->name) != 0) dumpSymbol(symbol, flags, fp); } } - } - else - { + } else { // dump all symbols for (unsigned ic = 0; ic < nsymbols; ic++) dumpSymbol(symbols[ic], flags, fp); } } -upx_uint64_t ElfLinker::getSymbolOffset(const char *name) const -{ +upx_uint64_t ElfLinker::getSymbolOffset(const char *name) const { const Symbol *symbol = findSymbol(name); if (symbol->section->output == NULL) return 0xdeaddead; return symbol->section->offset + symbol->offset; } -void ElfLinker::alignWithByte(unsigned len, unsigned char b) -{ +void ElfLinker::alignWithByte(unsigned len, unsigned char b) { memset(output + outputlen, b, len); outputlen += len; } -void ElfLinker::relocate1(const Relocation *rel, upx_byte *, - upx_uint64_t, const char *) -{ +void ElfLinker::relocate1(const Relocation *rel, upx_byte *, upx_uint64_t, const char *) { internal_error("unknown relocation type '%s\n", rel->type); } - /************************************************************************* // ElfLinker arch subclasses // FIXME: add more displacment overflow checks @@ -637,33 +562,28 @@ static void check8(const Relocation *rel, const upx_byte *location, int v, int d } #endif - -void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location, - upx_uint64_t value, const char *type) -{ +void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, + const char *type) { if (strncmp(type, "R_X86_64_", 9)) return super::relocate1(rel, location, value, type); type += 9; bool range_check = false; - if (strncmp(type, "PC", 2) == 0) - { + if (strncmp(type, "PC", 2) == 0) { value -= rel->section->offset + rel->offset; type += 2; range_check = true; } - if (strcmp(type, "8") == 0) - { + if (strcmp(type, "8") == 0) { int displ = (signed char) *location + (int) value; if (range_check && (displ < -128 || displ > 127)) - internal_error("target out of range (%d) in reloc %s:%x\n", - displ, rel->section->name, rel->offset); + internal_error("target out of range (%d) in reloc %s:%x\n", displ, rel->section->name, + rel->offset); *location += value; - } - else if (strcmp(type, "16") == 0) + } else if (strcmp(type, "16") == 0) set_le16(location, get_le16(location) + value); - else if (strncmp(type, "32", 2) == 0) // for "32" and "32S" + else if (strncmp(type, "32", 2) == 0) // for "32" and "32S" set_le32(location, get_le32(location) + value); else if (strcmp(type, "64") == 0) set_le64(location, get_le64(location) + value); @@ -671,95 +591,66 @@ void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location, super::relocate1(rel, location, value, type); } - -void ElfLinkerArmBE::relocate1(const Relocation *rel, upx_byte *location, - upx_uint64_t value, const char *type) -{ - if (strcmp(type, "R_ARM_PC24") == 0) - { +void ElfLinkerArmBE::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, + const char *type) { + if (strcmp(type, "R_ARM_PC24") == 0) { value -= rel->section->offset + rel->offset; - set_be24(1+ location, get_be24(1+ location) + value / 4); - } - else if (strcmp(type, "R_ARM_ABS32") == 0) - { + set_be24(1 + location, get_be24(1 + location) + value / 4); + } else if (strcmp(type, "R_ARM_ABS32") == 0) { set_be32(location, get_be32(location) + value); - } - else if (strcmp(type, "R_ARM_THM_CALL") == 0 - || strcmp(type, "R_ARM_THM_XPC22") == 0 - || strcmp(type, "R_ARM_THM_PC22") == 0 - ) - { + } else if (strcmp(type, "R_ARM_THM_CALL") == 0 || strcmp(type, "R_ARM_THM_XPC22") == 0 || + strcmp(type, "R_ARM_THM_PC22") == 0) { value -= rel->section->offset + rel->offset; value += ((get_be16(location) & 0x7ff) << 12); value += (get_be16(location + 2) & 0x7ff) << 1; set_be16(location, 0xf000 + ((value >> 12) & 0x7ff)); - set_be16(location + 2, 0xf800 + ((value >> 1) & 0x7ff)); + set_be16(location + 2, 0xf800 + ((value >> 1) & 0x7ff)); //(b, 0xF000 + ((v - 1) / 2) * 0x10000); - //set_be32(location, get_be32(location) + value / 4); - } - else if (0==strcmp("R_ARM_ABS8", type)) { + // set_be32(location, get_be32(location) + value / 4); + } else if (0 == strcmp("R_ARM_ABS8", type)) { *location += value; - } - else + } else super::relocate1(rel, location, value, type); } - -void ElfLinkerArmLE::relocate1(const Relocation *rel, upx_byte *location, - upx_uint64_t value, const char *type) -{ - if (strcmp(type, "R_ARM_PC24") == 0) - { +void ElfLinkerArmLE::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, + const char *type) { + if (strcmp(type, "R_ARM_PC24") == 0) { value -= rel->section->offset + rel->offset; set_le24(location, get_le24(location) + value / 4); - } - else if (strcmp(type, "R_ARM_ABS32") == 0) - { + } else if (strcmp(type, "R_ARM_ABS32") == 0) { set_le32(location, get_le32(location) + value); - } - else if (strcmp(type, "R_ARM_THM_CALL") == 0 - || strcmp(type, "R_ARM_THM_XPC22") == 0 - || strcmp(type, "R_ARM_THM_PC22") == 0 - ) - { + } else if (strcmp(type, "R_ARM_THM_CALL") == 0 || strcmp(type, "R_ARM_THM_XPC22") == 0 || + strcmp(type, "R_ARM_THM_PC22") == 0) { value -= rel->section->offset + rel->offset; value += ((get_le16(location) & 0x7ff) << 12); value += (get_le16(location + 2) & 0x7ff) << 1; set_le16(location, 0xf000 + ((value >> 12) & 0x7ff)); - set_le16(location + 2, 0xf800 + ((value >> 1) & 0x7ff)); + set_le16(location + 2, 0xf800 + ((value >> 1) & 0x7ff)); //(b, 0xF000 + ((v - 1) / 2) * 0x10000); - //set_le32(location, get_le32(location) + value / 4); - } - else if (0==strcmp("R_ARM_ABS8", type)) { + // set_le32(location, get_le32(location) + value / 4); + } else if (0 == strcmp("R_ARM_ABS8", type)) { *location += value; - } - else + } else super::relocate1(rel, location, value, type); } -void ElfLinkerArm64LE::relocate1(const Relocation *rel, upx_byte *location, - upx_uint64_t value, const char *type) -{ - if (strcmp(type, "R_AARCH64_CALL26") == 0) - { +void ElfLinkerArm64LE::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, + const char *type) { + if (strcmp(type, "R_AARCH64_CALL26") == 0) { value -= rel->section->offset + rel->offset; - set_le24(location, get_le24(location) + value / 4); // FIXME set_le26 - } - else if (strcmp(type, "R_AARCH64_ABS32") == 0) - { + set_le24(location, get_le24(location) + value / 4); // FIXME set_le26 + } else if (strcmp(type, "R_AARCH64_ABS32") == 0) { set_le32(location, get_le32(location) + value); - } - else + } else super::relocate1(rel, location, value, type); } - -void ElfLinkerM68k::alignCode(unsigned len) -{ +void ElfLinkerM68k::alignCode(unsigned len) { assert((len & 1) == 0); assert((outputlen & 1) == 0); for (unsigned i = 0; i < len; i += 2) @@ -767,50 +658,41 @@ void ElfLinkerM68k::alignCode(unsigned len) outputlen += len; } -void ElfLinkerM68k::relocate1(const Relocation *rel, upx_byte *location, - upx_uint64_t value, const char *type) -{ +void ElfLinkerM68k::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, + const char *type) { if (strncmp(type, "R_68K_", 6)) return super::relocate1(rel, location, value, type); type += 6; - if (strncmp(type, "PC", 2) == 0) - { + if (strncmp(type, "PC", 2) == 0) { value -= rel->section->offset + rel->offset; type += 2; } if (strcmp(type, "8") == 0) { *location += value; - } - else if (strcmp(type, "16") == 0) { + } else if (strcmp(type, "16") == 0) { set_be16(location, get_be16(location) + value); - } - else if (strcmp(type, "32") == 0) { + } else if (strcmp(type, "32") == 0) { set_be32(location, get_be32(location) + value); - } - else + } else super::relocate1(rel, location, value, type); } - -void ElfLinkerMipsBE::relocate1(const Relocation *rel, upx_byte *location, - upx_uint64_t value, const char *type) -{ -#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15)) -#define MIPS_LO(a) ((a) & 0xffff) -#define MIPS_PC16(a) ((a) >> 2) -#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2) +void ElfLinkerMipsBE::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, + const char *type) { +#define MIPS_HI(a) (((a) >> 16) + (((a) &0x8000) >> 15)) +#define MIPS_LO(a) ((a) &0xffff) +#define MIPS_PC16(a) ((a) >> 2) +#define MIPS_PC26(a) (((a) &0x0fffffff) >> 2) if (strcmp(type, "R_MIPS_HI16") == 0) - set_be16(2+location, get_be16(2+location) + MIPS_HI(value)); + set_be16(2 + location, get_be16(2 + location) + MIPS_HI(value)); else if (strcmp(type, "R_MIPS_LO16") == 0) - set_be16(2+location, get_be16(2+location) + MIPS_LO(value)); - else if (strcmp(type, "R_MIPS_PC16") == 0) - { + set_be16(2 + location, get_be16(2 + location) + MIPS_LO(value)); + else if (strcmp(type, "R_MIPS_PC16") == 0) { value -= rel->section->offset + rel->offset; - set_be16(2+location, get_be16(2+location) + MIPS_PC16(value)); - } - else if (strcmp(type, "R_MIPS_26") == 0) + set_be16(2 + location, get_be16(2 + location) + MIPS_PC16(value)); + } else if (strcmp(type, "R_MIPS_26") == 0) set_be32(location, get_be32(location) + MIPS_PC26(value)); else if (strcmp(type, "R_MIPS_32") == 0) set_be32(location, get_be32(location) + value); @@ -823,25 +705,21 @@ void ElfLinkerMipsBE::relocate1(const Relocation *rel, upx_byte *location, #undef MIPS_PC26 } - -void ElfLinkerMipsLE::relocate1(const Relocation *rel, upx_byte *location, - upx_uint64_t value, const char *type) -{ -#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15)) -#define MIPS_LO(a) ((a) & 0xffff) -#define MIPS_PC16(a) ((a) >> 2) -#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2) +void ElfLinkerMipsLE::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, + const char *type) { +#define MIPS_HI(a) (((a) >> 16) + (((a) &0x8000) >> 15)) +#define MIPS_LO(a) ((a) &0xffff) +#define MIPS_PC16(a) ((a) >> 2) +#define MIPS_PC26(a) (((a) &0x0fffffff) >> 2) if (strcmp(type, "R_MIPS_HI16") == 0) set_le16(location, get_le16(location) + MIPS_HI(value)); else if (strcmp(type, "R_MIPS_LO16") == 0) set_le16(location, get_le16(location) + MIPS_LO(value)); - else if (strcmp(type, "R_MIPS_PC16") == 0) - { + else if (strcmp(type, "R_MIPS_PC16") == 0) { value -= rel->section->offset + rel->offset; set_le16(location, get_le16(location) + MIPS_PC16(value)); - } - else if (strcmp(type, "R_MIPS_26") == 0) + } else if (strcmp(type, "R_MIPS_26") == 0) set_le32(location, get_le32(location) + MIPS_PC26(value)); else if (strcmp(type, "R_MIPS_32") == 0) set_le32(location, get_le32(location) + value); @@ -854,22 +732,18 @@ void ElfLinkerMipsLE::relocate1(const Relocation *rel, upx_byte *location, #undef MIPS_PC26 } - -void ElfLinkerPpc32::relocate1(const Relocation *rel, upx_byte *location, - upx_uint64_t value, const char *type) -{ +void ElfLinkerPpc32::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, + const char *type) { if (strncmp(type, "R_PPC_", 6)) return super::relocate1(rel, location, value, type); type += 6; - if (strcmp(type, "ADDR32") == 0) - { + if (strcmp(type, "ADDR32") == 0) { set_be32(location, get_be32(location) + value); return; } - if (strncmp(type, "REL", 3) == 0) - { + if (strncmp(type, "REL", 3) == 0) { value -= rel->section->offset + rel->offset; type += 3; } @@ -878,33 +752,27 @@ void ElfLinkerPpc32::relocate1(const Relocation *rel, upx_byte *location, // Note that original (*location).displ is ignored. if (strcmp(type, "24") == 0) { - if (3& value) + if (3 & value) internal_error("unaligned word diplacement"); // FIXME: displacment overflow? - set_be32(location, (0xfc000003 & get_be32(location)) + - (0x03fffffc & value)); - } - else if (strcmp(type, "14") == 0) { - if (3& value) + set_be32(location, (0xfc000003 & get_be32(location)) + (0x03fffffc & value)); + } else if (strcmp(type, "14") == 0) { + if (3 & value) internal_error("unaligned word diplacement"); // FIXME: displacment overflow? - set_be32(location, (0xffff0003 & get_be32(location)) + - (0x0000fffc & value)); - } - else + set_be32(location, (0xffff0003 & get_be32(location)) + (0x0000fffc & value)); + } else super::relocate1(rel, location, value, type); } -void ElfLinkerPpc64le::relocate1(const Relocation *rel, upx_byte *location, - upx_uint64_t value, const char *type) -{ +void ElfLinkerPpc64le::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, + const char *type) { if (strncmp(type, "R_PPC64_REL", 11)) return super::relocate1(rel, location, value, type); type += 11; bool range_check = false; - if (strncmp(type, "PC", 2) == 0) - { + if (strncmp(type, "PC", 2) == 0) { type += 2; range_check = true; } @@ -912,21 +780,19 @@ void ElfLinkerPpc64le::relocate1(const Relocation *rel, upx_byte *location, /* value will hold relative displacement */ value -= rel->section->offset + rel->offset; - if (strcmp(type, "8") == 0) - { + if (strcmp(type, "8") == 0) { int displ = (signed char) *location + (int) value; if (range_check && (displ < -128 || displ > 127)) - internal_error("target out of range (%d) in reloc %s:%x\n", - displ, rel->section->name, rel->offset); + internal_error("target out of range (%d) in reloc %s:%x\n", displ, rel->section->name, + rel->offset); *location += value; - } - else if (strncmp(type, "14", 2) == 0) // for "32" and "32S" + } else if (strncmp(type, "14", 2) == 0) // for "32" and "32S" set_le16(location, get_le16(location) + value); else if (strcmp(type, "16") == 0) set_le16(location, get_le16(location) + value); - else if (strncmp(type, "24", 2) == 0) // for "32" and "32S" + else if (strncmp(type, "24", 2) == 0) // for "32" and "32S" set_le24(location, get_le24(location) + value); - else if (strncmp(type, "32", 2) == 0) // for "32" and "32S" + else if (strncmp(type, "32", 2) == 0) // for "32" and "32S" set_le32(location, get_le32(location) + value); else if (strcmp(type, "64") == 0) set_le64(location, get_le64(location) + value); @@ -934,31 +800,26 @@ void ElfLinkerPpc64le::relocate1(const Relocation *rel, upx_byte *location, super::relocate1(rel, location, value, type); } - -void ElfLinkerX86::relocate1(const Relocation *rel, upx_byte *location, - upx_uint64_t value, const char *type) -{ +void ElfLinkerX86::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, + const char *type) { if (strncmp(type, "R_386_", 6)) return super::relocate1(rel, location, value, type); type += 6; bool range_check = false; - if (strncmp(type, "PC", 2) == 0) - { + if (strncmp(type, "PC", 2) == 0) { value -= rel->section->offset + rel->offset; type += 2; range_check = true; } - if (strcmp(type, "8") == 0) - { + if (strcmp(type, "8") == 0) { int displ = (signed char) *location + (int) value; if (range_check && (displ < -128 || displ > 127)) - internal_error("target out of range (%d,%d,%d) in reloc %s:%x\n", - displ, *location, value, rel->section->name, rel->offset); + internal_error("target out of range (%d,%d,%d) in reloc %s:%x\n", displ, *location, + value, rel->section->name, rel->offset); *location += value; - } - else if (strcmp(type, "16") == 0) + } else if (strcmp(type, "16") == 0) set_le16(location, get_le16(location) + value); else if (strcmp(type, "32") == 0) set_le32(location, get_le32(location) + value); diff --git a/src/linker.h b/src/linker.h index 5c77aa82..c83798af 100644 --- a/src/linker.h +++ b/src/linker.h @@ -25,52 +25,50 @@ */ - #ifndef __UPX_LINKER_H #define __UPX_LINKER_H 1 - /************************************************************************* // ElfLinker **************************************************************************/ -class ElfLinker : private noncopyable -{ +class ElfLinker : private noncopyable { friend class Packer; + public: const N_BELE_RTP::AbstractPolicy *bele; // target endianness protected: - struct Section; - struct Symbol; - struct Relocation; + struct Section; + struct Symbol; + struct Relocation; - upx_byte *input; - int inputlen; - upx_byte *output; - int outputlen; + upx_byte *input; + int inputlen; + upx_byte *output; + int outputlen; - Section *head; - Section *tail; + Section *head; + Section *tail; - Section **sections; - Symbol **symbols; - Relocation **relocations; + Section **sections; + Symbol **symbols; + Relocation **relocations; - unsigned nsections; - unsigned nsections_capacity; - unsigned nsymbols; - unsigned nsymbols_capacity; - unsigned nrelocations; - unsigned nrelocations_capacity; + unsigned nsections; + unsigned nsections_capacity; + unsigned nsymbols; + unsigned nsymbols_capacity; + unsigned nrelocations; + unsigned nrelocations_capacity; - bool reloc_done; + bool reloc_done; protected: - void preprocessSections(char *start, char const *end); - void preprocessSymbols(char *start, char const *end); - void preprocessRelocations(char *start, char const *end); - Section *findSection(const char *name, bool fatal=true) const; - Symbol *findSymbol(const char *name, bool fatal=true) const; + void preprocessSections(char *start, char *end); + void preprocessSymbols(char *start, char *end); + void preprocessRelocations(char *start, char *end); + Section *findSection(const char *name, bool fatal = true) const; + Symbol *findSymbol(const char *name, bool fatal = true) const; Symbol *addSymbol(const char *name, const char *section, upx_uint64_t offset); Relocation *addRelocation(const char *section, unsigned off, const char *type, @@ -81,7 +79,7 @@ public: virtual ~ElfLinker(); virtual void init(const void *pdata, int plen); - //virtual void setLoaderAlignOffset(int phase); + // virtual void setLoaderAlignOffset(int phase); virtual int addLoader(const char *sname); void addLoader(const char *s, va_list ap); #if 1 && (ACC_CC_CLANG || (ACC_CC_GNUC >= 0x040100)) @@ -90,14 +88,14 @@ public: void __acc_cdecl_va addLoaderVA(const char *s, ...); #endif virtual Section *addSection(const char *sname, const void *sdata, int slen, unsigned p2align); - virtual int getSection(const char *sname, int *slen=NULL) const; + virtual int getSection(const char *sname, int *slen = NULL) const; virtual int getSectionSize(const char *sname) const; - virtual upx_byte *getLoader(int *llen=NULL) const; + virtual upx_byte *getLoader(int *llen = NULL) const; virtual void defineSymbol(const char *name, upx_uint64_t value); virtual upx_uint64_t getSymbolOffset(const char *) const; virtual void dumpSymbol(const Symbol *, unsigned flags, FILE *fp) const; - virtual void dumpSymbols(unsigned flags=0, FILE *fp=NULL) const; + virtual void dumpSymbols(unsigned flags = 0, FILE *fp = NULL) const; void alignWithByte(unsigned len, unsigned char b); virtual void alignCode(unsigned len) { alignWithByte(len, 0); } @@ -105,36 +103,32 @@ public: protected: virtual void relocate(); - virtual void relocate1(const Relocation *, upx_byte *location, - upx_uint64_t value, const char *type); + virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, + const char *type); // target endianness abstraction - unsigned get_te16(const void *p) const { return bele->get16(p); } - unsigned get_te32(const void *p) const { return bele->get32(p); } - upx_uint64_t get_te64(const void *p) const { return bele->get64(p); } - void set_te16(void *p, unsigned v) const { bele->set16(p, v); } - void set_te32(void *p, unsigned v) const { bele->set32(p, v); } + unsigned get_te16(const void *p) const { return bele->get16(p); } + unsigned get_te32(const void *p) const { return bele->get32(p); } + upx_uint64_t get_te64(const void *p) const { return bele->get64(p); } + void set_te16(void *p, unsigned v) const { bele->set16(p, v); } + void set_te32(void *p, unsigned v) const { bele->set32(p, v); } void set_te64(void *p, upx_uint64_t v) const { bele->set64(p, v); } }; - -struct ElfLinker::Section : private noncopyable -{ +struct ElfLinker::Section : private noncopyable { char *name; void *input; upx_byte *output; unsigned size; upx_uint64_t offset; - unsigned p2align; // log2 + unsigned p2align; // log2 Section *next; - Section(const char *n, const void *i, unsigned s, unsigned a=0); + Section(const char *n, const void *i, unsigned s, unsigned a = 0); ~Section(); }; - -struct ElfLinker::Symbol : private noncopyable -{ +struct ElfLinker::Symbol : private noncopyable { char *name; Section *section; upx_uint64_t offset; @@ -143,124 +137,115 @@ struct ElfLinker::Symbol : private noncopyable ~Symbol(); }; - -struct ElfLinker::Relocation : private noncopyable -{ +struct ElfLinker::Relocation : private noncopyable { const Section *section; unsigned offset; const char *type; const Symbol *value; - upx_uint64_t add; // used in .rela relocations + upx_uint64_t add; // used in .rela relocations - Relocation(const Section *s, unsigned o, const char *t, - const Symbol *v, upx_uint64_t a); + Relocation(const Section *s, unsigned o, const char *t, const Symbol *v, upx_uint64_t a); }; - /************************************************************************* // ElfLinker arch subclasses **************************************************************************/ -class ElfLinkerAMD64 : public ElfLinker -{ +class ElfLinkerAMD64 : public ElfLinker { typedef ElfLinker super; + protected: virtual void alignCode(unsigned len) { alignWithByte(len, 0x90); } - virtual void relocate1(const Relocation *, upx_byte *location, - upx_uint64_t value, const char *type); + virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, + const char *type); }; - -class ElfLinkerArmBE : public ElfLinker -{ +class ElfLinkerArmBE : public ElfLinker { typedef ElfLinker super; + public: ElfLinkerArmBE() { bele = &N_BELE_RTP::be_policy; } + protected: - virtual void relocate1(const Relocation *, upx_byte *location, - upx_uint64_t value, const char *type); + virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, + const char *type); }; - -class ElfLinkerArmLE : public ElfLinker -{ +class ElfLinkerArmLE : public ElfLinker { typedef ElfLinker super; + protected: - virtual void relocate1(const Relocation *, upx_byte *location, - upx_uint64_t value, const char *type); + virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, + const char *type); }; -class ElfLinkerArm64LE : public ElfLinker -{ +class ElfLinkerArm64LE : public ElfLinker { typedef ElfLinker super; + protected: - virtual void relocate1(const Relocation *, upx_byte *location, - upx_uint64_t value, const char *type); + virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, + const char *type); }; - -class ElfLinkerM68k : public ElfLinker -{ +class ElfLinkerM68k : public ElfLinker { typedef ElfLinker super; + public: ElfLinkerM68k() { bele = &N_BELE_RTP::be_policy; } + protected: virtual void alignCode(unsigned len); - virtual void relocate1(const Relocation *, upx_byte *location, - upx_uint64_t value, const char *type); + virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, + const char *type); }; - -class ElfLinkerMipsBE : public ElfLinker -{ +class ElfLinkerMipsBE : public ElfLinker { typedef ElfLinker super; + public: ElfLinkerMipsBE() { bele = &N_BELE_RTP::be_policy; } + protected: - virtual void relocate1(const Relocation *, upx_byte *location, - upx_uint64_t value, const char *type); + virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, + const char *type); }; - -class ElfLinkerMipsLE : public ElfLinker -{ +class ElfLinkerMipsLE : public ElfLinker { typedef ElfLinker super; + protected: - virtual void relocate1(const Relocation *, upx_byte *location, - upx_uint64_t value, const char *type); + virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, + const char *type); }; - -class ElfLinkerPpc32 : public ElfLinker -{ +class ElfLinkerPpc32 : public ElfLinker { typedef ElfLinker super; + public: ElfLinkerPpc32() { bele = &N_BELE_RTP::be_policy; } + protected: - virtual void relocate1(const Relocation *, upx_byte *location, - upx_uint64_t value, const char *type); + virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, + const char *type); }; -class ElfLinkerPpc64le : public ElfLinker -{ +class ElfLinkerPpc64le : public ElfLinker { typedef ElfLinker super; + protected: - virtual void relocate1(const Relocation *, upx_byte *location, - upx_uint64_t value, const char *type); + virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, + const char *type); }; - -class ElfLinkerX86 : public ElfLinker -{ +class ElfLinkerX86 : public ElfLinker { typedef ElfLinker super; + protected: virtual void alignCode(unsigned len) { alignWithByte(len, 0x90); } - virtual void relocate1(const Relocation *, upx_byte *location, - upx_uint64_t value, const char *type); + virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, + const char *type); }; - - #endif /* already included */ /* vim:set ts=4 sw=4 et: */ diff --git a/src/lzma-sdk b/src/lzma-sdk index 33fb09d2..426fe82d 160000 --- a/src/lzma-sdk +++ b/src/lzma-sdk @@ -1 +1 @@ -Subproject commit 33fb09d29159f9dde2ddae9fe6875f8614d28ca3 +Subproject commit 426fe82d122e2cf140a86751055ee523378fe2ef diff --git a/src/p_mach.cpp b/src/p_mach.cpp index 352ede77..f157a5ac 100644 --- a/src/p_mach.cpp +++ b/src/p_mach.cpp @@ -1666,7 +1666,7 @@ int PackMachBase::canUnpack() } if (!strcmp("__LINKEDIT", segptr->segname)) { offLINK = segptr->fileoff; - if (offLINK < pos_next) { + if (offLINK < (off_t) pos_next) { offLINK = pos_next; } } diff --git a/src/stub/powerpc-darwin.macho-upxmain.exe b/src/stub/powerpc-darwin.macho-upxmain.exe old mode 100755 new mode 100644 diff --git a/src/stub/scripts/xstrip.py b/src/stub/scripts/xstrip.py index 466ff772..e86ba7d1 100644 --- a/src/stub/scripts/xstrip.py +++ b/src/stub/scripts/xstrip.py @@ -178,8 +178,7 @@ def do_file(fn): # FIXME / TODO pass else: - pass - #assert pos == len(odata), ("unexpected strip_with_dump", pos, len(odata)) + assert pos == len(odata), ("unexpected strip_with_dump", pos, len(odata)) else: if pos >= 0: odata = idata[:pos] diff --git a/src/version.h b/src/version.h index 6aeb9bc4..cd897354 100644 --- a/src/version.h +++ b/src/version.h @@ -1,8 +1,8 @@ #define UPX_VERSION_HEX 0x035c00 /* 03.92.00 */ -#define UPX_VERSION_STRING "3.92-BETA" +#define UPX_VERSION_STRING "3.92" #define UPX_VERSION_STRING4 "3.92" -#define UPX_VERSION_DATE "Sep 25th 2016" -#define UPX_VERSION_DATE_ISO "2016-09-25" +#define UPX_VERSION_DATE "Nov 27th 2016" +#define UPX_VERSION_DATE_ISO "2016-11-25" #define UPX_VERSION_YEAR "2016" /* vim:set ts=4 sw=4 et: */