Resynced with upx 1.2 branch.
committer: mfx <mfx> 1031577224 +0000
This commit is contained in:
parent
1439dace83
commit
9b079b371d
3
TODO
3
TODO
@ -13,6 +13,9 @@ UPX TODO list. Last updated 2002-07-16.
|
||||
|
||||
- check all <const_cast> to make sure they are not invalid
|
||||
|
||||
- throwNotCompressible() is not a real error, so make the output nicer
|
||||
(info: bla bla). Also ui.cpp (total_*).
|
||||
|
||||
|
||||
TEST:
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
GNUmakefile
|
||||
*.0??
|
||||
*.dat
|
||||
*.idb
|
||||
@ -10,6 +11,7 @@
|
||||
.gdbinit
|
||||
.Attic
|
||||
.deps
|
||||
compress_nrv.*
|
||||
upx
|
||||
upx_nrv
|
||||
upx_nrv.*
|
||||
|
||||
45
src/Makefile
45
src/Makefile
@ -24,6 +24,8 @@ ifeq ($(strip $(UCLDIR)),)
|
||||
UCLDIR = $(HOME)/local/src/ucl-1.01
|
||||
endif
|
||||
|
||||
##target =
|
||||
|
||||
DEBUG = 0
|
||||
|
||||
|
||||
@ -75,13 +77,12 @@ OBJECTS1 = \
|
||||
packer$o packerf$o packhead$o packmast$o \
|
||||
p_com$o p_djgpp2$o p_elks$o p_exe$o \
|
||||
p_lx_elf$o p_lx_exc$o p_lx_sep$o p_lx_sh$o \
|
||||
p_psx$o \
|
||||
p_sys$o p_tmt$o p_tos$o \
|
||||
p_psx$o p_sys$o p_tmt$o p_tos$o \
|
||||
p_unix$o p_vmlinz$o p_w16ne$o p_w32pe$o p_wcle$o
|
||||
|
||||
# no exceptions or RTTI
|
||||
OBJECTS2 = \
|
||||
filteri$o help$o main$o mygetopt$o util$o \
|
||||
filteri$o help$o main$o mygetopt$o snprintf$o util$o \
|
||||
c_init$o c_file$o c_none$o c_screen$o \
|
||||
s_object$o s_djgpp2$o s_vcsa$o s_win32$o
|
||||
|
||||
@ -108,7 +109,7 @@ e =
|
||||
CC = gcc
|
||||
DEFS =
|
||||
INCLUDES =
|
||||
INCLUDES = -I. -I$(srcdir)
|
||||
##INCLUDES = -I. -I$(srcdir)
|
||||
CFLAGS_OUTPUT = -o $@
|
||||
|
||||
LINK_EXE = $(CXXLD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
|
||||
@ -168,14 +169,15 @@ UCLDIR:=$(strip $(subst \,/,$(UCLDIR)))
|
||||
NRVDIR:=$(strip $(subst \,/,$(NRVDIR)))
|
||||
u = ucl
|
||||
U = UCL
|
||||
upx_exe = upx$e
|
||||
upx_exe_tail =
|
||||
include $(srcdir)/Makefile.inc
|
||||
ifneq ($(strip $(wildcard $(NRVDIR)/include/nrv)),)
|
||||
u = nrv
|
||||
U = NRV
|
||||
upx_exe = upx_$u$e
|
||||
upx_exe_tail = _$(u)
|
||||
include $(srcdir)/Makefile.inc
|
||||
endif
|
||||
upx_exe = upx$(upx_exe_tail)$(e)
|
||||
|
||||
override tmp := -Wl,--rpath,
|
||||
LDRPATH := $(addprefix $(tmp),$(LIBDIRS))
|
||||
@ -279,6 +281,12 @@ CC = m68k-atari-mint-gcc
|
||||
CC += -m68040
|
||||
endif
|
||||
|
||||
ifeq ($(target),cross-mint-m68020-60)
|
||||
e = .ttp
|
||||
CC = m68k-atari-mint-gcc
|
||||
CC += -m68020-60 -m68881
|
||||
endif
|
||||
|
||||
|
||||
###
|
||||
### djgpp2
|
||||
@ -290,8 +298,8 @@ CC += -march=i386 -mcpu=i586
|
||||
##CFLAGS_M += -mno-schedule-prologue
|
||||
CFLAGS_WERROR = -Werror
|
||||
STUBEDIT_EXE = stubedit $@ bufsize=0xfc00
|
||||
ifneq ($(strip $(wildcard $(DJDIR)/bin/mfxdjstubify.exe)),)
|
||||
ifneq ($(strip $(wildcard $(DJDIR)/bin/cwsdstub.exe)),)
|
||||
ifneq ($(strip $(wildcard $(DJDIR)/bin/mfxdjstubify.ex[eE])),)
|
||||
ifneq ($(strip $(wildcard $(DJDIR)/bin/cwsdstub.ex[eE])),)
|
||||
STUBIFY_EXE = mfxdjstubify -v -s $(DJDIR)/bin/cwsdstub.exe $(upx_exe)
|
||||
endif
|
||||
endif
|
||||
@ -481,9 +489,14 @@ endif # wcc
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // malloc debuggers and memory checkers
|
||||
# // malloc debuggers and memory checkers - somewhat obsolete, use valgrind
|
||||
# ************************************************************************/
|
||||
|
||||
ifeq (1,2)
|
||||
# compile in extra valgrind support
|
||||
CFLAGS += -DWITH_VALGRIND
|
||||
endif
|
||||
|
||||
ifeq (1,2)
|
||||
LDLIBS += -lefence
|
||||
endif
|
||||
@ -500,11 +513,6 @@ ifeq (1,2)
|
||||
##LDFLAGS += -Wl,-defsym,_DYNAMIC=0
|
||||
endif
|
||||
|
||||
ifeq (1,2)
|
||||
CFLAGS += -DWITH_MSS
|
||||
LDLIBS += -lmss
|
||||
endif
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // finish settings
|
||||
@ -550,7 +558,7 @@ CXXFLAGS2 = $(CXXFLAGS1)
|
||||
|
||||
all: $(upx_exe)
|
||||
|
||||
.PHONY: all unupx mostlyclean clean distclean maintainer-clean untabify tags
|
||||
.PHONY: all mostlyclean clean distclean maintainer-clean untabify tags
|
||||
|
||||
$(upx_exe): $(OBJECTS) $(LIBS) $(RESOURCES)
|
||||
$(LINK_EXE)
|
||||
@ -559,13 +567,6 @@ $(upx_exe): $(OBJECTS) $(LIBS) $(RESOURCES)
|
||||
$(CHMOD_EXE)
|
||||
|
||||
|
||||
unupx:
|
||||
$(MAKE) target=vc6 unupx.dll
|
||||
|
||||
unupx.dll: $(OBJECTS) $(LIBS)
|
||||
$(LINK_DLL)
|
||||
|
||||
|
||||
mostlyclean:
|
||||
-rm -f *.d *.err *.i *.log *.map *~ gdb-trans*
|
||||
|
||||
|
||||
40
src/bele.h
40
src/bele.h
@ -36,7 +36,7 @@
|
||||
|
||||
inline unsigned get_be16(const void *bb)
|
||||
{
|
||||
const upx_bytep b = reinterpret_cast<const upx_bytep>(bb);
|
||||
const upx_bytep b = (const upx_bytep) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[1] << 0;
|
||||
v |= (unsigned) b[0] << 8;
|
||||
@ -45,7 +45,7 @@ inline unsigned get_be16(const void *bb)
|
||||
|
||||
inline void set_be16(void *bb, unsigned v)
|
||||
{
|
||||
upx_bytep b = reinterpret_cast<upx_bytep>(bb);
|
||||
upx_bytep b = (upx_bytep) bb;
|
||||
b[1] = (unsigned char) (v >> 0);
|
||||
b[0] = (unsigned char) (v >> 8);
|
||||
}
|
||||
@ -53,7 +53,7 @@ inline void set_be16(void *bb, unsigned v)
|
||||
|
||||
inline unsigned get_be32(const void *bb)
|
||||
{
|
||||
const upx_bytep b = reinterpret_cast<const upx_bytep>(bb);
|
||||
const upx_bytep b = (const upx_bytep) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[3] << 0;
|
||||
v |= (unsigned) b[2] << 8;
|
||||
@ -64,7 +64,7 @@ inline unsigned get_be32(const void *bb)
|
||||
|
||||
inline void set_be32(void *bb, unsigned v)
|
||||
{
|
||||
upx_bytep b = reinterpret_cast<upx_bytep>(bb);
|
||||
upx_bytep b = (upx_bytep) bb;
|
||||
b[3] = (unsigned char) (v >> 0);
|
||||
b[2] = (unsigned char) (v >> 8);
|
||||
b[1] = (unsigned char) (v >> 16);
|
||||
@ -74,23 +74,23 @@ inline void set_be32(void *bb, unsigned v)
|
||||
|
||||
inline unsigned get_le16(const void *bb)
|
||||
{
|
||||
const upx_bytep b = reinterpret_cast<const upx_bytep>(bb);
|
||||
unsigned v;
|
||||
#if defined(__i386__)
|
||||
v = * (const unsigned short *) b;
|
||||
return * (const unsigned short *) bb;
|
||||
#else
|
||||
const upx_bytep b = (const upx_bytep) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[0] << 0;
|
||||
v |= (unsigned) b[1] << 8;
|
||||
#endif
|
||||
return v;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_le16(void *bb, unsigned v)
|
||||
{
|
||||
upx_bytep b = reinterpret_cast<upx_bytep>(bb);
|
||||
#if defined(__i386__)
|
||||
(* (unsigned short *) b) = (unsigned short) v;
|
||||
(* (unsigned short *) bb) = (unsigned short) (v & 0xffff);
|
||||
#else
|
||||
upx_bytep b = (upx_bytep) bb;
|
||||
b[0] = (unsigned char) (v >> 0);
|
||||
b[1] = (unsigned char) (v >> 8);
|
||||
#endif
|
||||
@ -99,7 +99,7 @@ inline void set_le16(void *bb, unsigned v)
|
||||
|
||||
inline unsigned get_le24(const void *bb)
|
||||
{
|
||||
const upx_bytep b = reinterpret_cast<const upx_bytep>(bb);
|
||||
const upx_bytep b = (const upx_bytep) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[0] << 0;
|
||||
v |= (unsigned) b[1] << 8;
|
||||
@ -109,7 +109,7 @@ inline unsigned get_le24(const void *bb)
|
||||
|
||||
inline void set_le24(void *bb, unsigned v)
|
||||
{
|
||||
upx_bytep b = reinterpret_cast<upx_bytep>(bb);
|
||||
upx_bytep b = (upx_bytep) bb;
|
||||
b[0] = (unsigned char) (v >> 0);
|
||||
b[1] = (unsigned char) (v >> 8);
|
||||
b[2] = (unsigned char) (v >> 16);
|
||||
@ -118,25 +118,25 @@ inline void set_le24(void *bb, unsigned v)
|
||||
|
||||
inline unsigned get_le32(const void *bb)
|
||||
{
|
||||
const upx_bytep b = reinterpret_cast<const upx_bytep>(bb);
|
||||
unsigned v;
|
||||
#if defined(__i386__)
|
||||
v = * (const unsigned *) b;
|
||||
return * (const unsigned *) bb;
|
||||
#else
|
||||
const upx_bytep b = (const upx_bytep) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[0] << 0;
|
||||
v |= (unsigned) b[1] << 8;
|
||||
v |= (unsigned) b[2] << 16;
|
||||
v |= (unsigned) b[3] << 24;
|
||||
#endif
|
||||
return v;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_le32(void *bb, unsigned v)
|
||||
{
|
||||
upx_bytep b = reinterpret_cast<upx_bytep>(bb);
|
||||
#if defined(__i386__)
|
||||
(* (unsigned *) b) = v;
|
||||
(* (unsigned *) bb) = v;
|
||||
#else
|
||||
upx_bytep b = (upx_bytep) bb;
|
||||
b[0] = (unsigned char) (v >> 0);
|
||||
b[1] = (unsigned char) (v >> 8);
|
||||
b[2] = (unsigned char) (v >> 16);
|
||||
@ -318,6 +318,10 @@ int be16_compare(const void *e1, const void *e2);
|
||||
int be32_compare(const void *e1, const void *e2);
|
||||
int le16_compare(const void *e1, const void *e2);
|
||||
int le32_compare(const void *e1, const void *e2);
|
||||
int be16_compare_signed(const void *e1, const void *e2);
|
||||
int be32_compare_signed(const void *e1, const void *e2);
|
||||
int le16_compare_signed(const void *e1, const void *e2);
|
||||
int le32_compare_signed(const void *e1, const void *e2);
|
||||
|
||||
|
||||
// just for testing...
|
||||
|
||||
@ -147,8 +147,8 @@ void con_fprintf(FILE *f, const char *format, ...)
|
||||
va_list args;
|
||||
char buf[80*25];
|
||||
|
||||
va_start(args,format);
|
||||
upx_vsnprintf(buf,sizeof(buf),format,args);
|
||||
va_start(args, format);
|
||||
upx_vsnprintf(buf, sizeof(buf), format,args);
|
||||
va_end(args);
|
||||
|
||||
if (con == me)
|
||||
|
||||
242
src/compress.ch
Normal file
242
src/compress.ch
Normal file
@ -0,0 +1,242 @@
|
||||
/* compress.ch --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(upx_adler32)
|
||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
||||
{
|
||||
if (len == 0)
|
||||
return adler;
|
||||
assert(buf != NULL);
|
||||
return ucl_adler32(adler, (const ucl_bytep)buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(upx_crc32)
|
||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
||||
{
|
||||
if (len == 0)
|
||||
return crc;
|
||||
assert(buf != NULL);
|
||||
return ucl_crc32(crc, (const ucl_bytep)buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(upx_compress)
|
||||
|
||||
int upx_compress ( const upx_bytep src, upx_uint src_len,
|
||||
upx_bytep dst, upx_uintp dst_len,
|
||||
upx_progress_callback_t *cb,
|
||||
int method, int level,
|
||||
const struct upx_compress_config_t *conf_parm,
|
||||
upx_uintp result )
|
||||
{
|
||||
struct upx_compress_config_t conf;
|
||||
upx_uint result_buffer[16];
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
assert(level > 0);
|
||||
memset(&conf, 0xff, sizeof(conf));
|
||||
if (conf_parm)
|
||||
conf = *conf_parm; // struct copy
|
||||
if (!result)
|
||||
result = result_buffer;
|
||||
|
||||
// assume no info available - fill in worst case results
|
||||
//result[0] = 1; // min_offset_found - NOT USED
|
||||
result[1] = src_len - 1; // max_offset_found
|
||||
//result[2] = 2; // min_match_found - NOT USED
|
||||
result[3] = src_len - 1; // max_match_found
|
||||
//result[4] = 1; // min_run_found - NOT USED
|
||||
result[5] = src_len; // max_run_found
|
||||
result[6] = 1; // first_offset_found
|
||||
//result[7] = 999999; // same_match_offsets_found - NOT USED
|
||||
|
||||
// prepare bit-buffer settings
|
||||
conf.bb_endian = 0;
|
||||
conf.bb_size = 0;
|
||||
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16)
|
||||
{
|
||||
int n = (method - M_NRV2B_LE32) % 3;
|
||||
if (n == 0)
|
||||
conf.bb_size = 32;
|
||||
else if (n == 1)
|
||||
conf.bb_size = 8;
|
||||
else
|
||||
conf.bb_size = 16;
|
||||
}
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
|
||||
// optimize compression parms
|
||||
if (level <= 3 && conf.max_offset == UPX_UINT_MAX)
|
||||
conf.max_offset = 8*1024-1;
|
||||
else if (level == 4 && conf.max_offset == UPX_UINT_MAX)
|
||||
conf.max_offset = 32*1024-1;
|
||||
|
||||
if M_IS_NRV2B(method)
|
||||
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
|
||||
cb, level, &conf, result);
|
||||
else if M_IS_NRV2D(method)
|
||||
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
|
||||
cb, level, &conf, result);
|
||||
#if defined(ALG_NRV2E)
|
||||
else if M_IS_NRV2E(method)
|
||||
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
|
||||
cb, level, &conf, result);
|
||||
#endif
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif /* upx_compress */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(upx_decompress)
|
||||
|
||||
int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
||||
upx_bytep dst, upx_uintp dst_len,
|
||||
int method )
|
||||
{
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
#if defined(ALG_NRV2E)
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif /* upx_decompress */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(upx_test_overlap)
|
||||
|
||||
int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
||||
upx_uint src_len, upx_uintp dst_len,
|
||||
int method )
|
||||
{
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
#if defined(ALG_NRV2E)
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif /* upx_test_overlap */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
365
src/compress.cpp
365
src/compress.cpp
@ -27,370 +27,23 @@
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "version.h"
|
||||
|
||||
#if 0 && defined(WITH_NRV) && defined(__i386__)
|
||||
# define NRV_USE_ASM
|
||||
#endif
|
||||
#if 0 && defined(WITH_UCL) && defined(__i386__)
|
||||
# define UCL_USE_ASM
|
||||
#endif
|
||||
|
||||
#if defined(WITH_NRV)
|
||||
# include <nrv/nrv2b.h>
|
||||
# include <nrv/nrv2d.h>
|
||||
//# include <nrv/nrv2e.h>
|
||||
# if !defined(NRV_VERSION) || (NRV_VERSION < 0x008000L)
|
||||
# error
|
||||
# endif
|
||||
NRV_EXTERN_CDECL(int) nrv2b_99_compress_internal(const upx_byte *, ...);
|
||||
NRV_EXTERN_CDECL(int) nrv2d_99_compress_internal(const upx_byte *, ...);
|
||||
NRV_EXTERN_CDECL(int) nrv2e_99_compress_internal(const upx_byte *, ...);
|
||||
# include "compress_nrv.ch"
|
||||
#elif defined(WITH_UCL)
|
||||
# define nrv2b_99_compress_internal ucl_nrv2b_99_compress
|
||||
# define nrv2d_99_compress_internal ucl_nrv2d_99_compress
|
||||
# define nrv2e_99_compress_internal ucl_nrv2e_99_compress
|
||||
#endif
|
||||
#if 1 && defined(WITH_NRV) && defined(NRV_USE_ASM)
|
||||
# if 1 && defined(NRV_USE_ASM)
|
||||
# define nrv2b_decompress_safe_8 nrv2b_decompress_asm_safe_8
|
||||
# define nrv2b_decompress_safe_le16 nrv2b_decompress_asm_safe_le16
|
||||
# define nrv2b_decompress_safe_le32 nrv2b_decompress_asm_safe_le32
|
||||
# define nrv2d_decompress_safe_8 nrv2d_decompress_asm_safe_8
|
||||
# define nrv2d_decompress_safe_le16 nrv2d_decompress_asm_safe_le16
|
||||
# define nrv2d_decompress_safe_le32 nrv2d_decompress_asm_safe_le32
|
||||
# define nrv2e_decompress_safe_8 nrv2e_decompress_asm_safe_8
|
||||
# define nrv2e_decompress_safe_le16 nrv2e_decompress_asm_safe_le16
|
||||
# define nrv2e_decompress_safe_le32 nrv2e_decompress_asm_safe_le32
|
||||
# endif
|
||||
NRV_EXTERN_CDECL(int) nrv2b_decompress_safe_8(const upx_byte *, ...);
|
||||
NRV_EXTERN_CDECL(int) nrv2b_decompress_safe_le16(const upx_byte *, ...);
|
||||
NRV_EXTERN_CDECL(int) nrv2b_decompress_safe_le32(const upx_byte *, ...);
|
||||
NRV_EXTERN_CDECL(int) nrv2d_decompress_safe_8(const upx_byte *, ...);
|
||||
NRV_EXTERN_CDECL(int) nrv2d_decompress_safe_le16(const upx_byte *, ...);
|
||||
NRV_EXTERN_CDECL(int) nrv2d_decompress_safe_le32(const upx_byte *, ...);
|
||||
NRV_EXTERN_CDECL(int) nrv2e_decompress_safe_8(const upx_byte *, ...);
|
||||
NRV_EXTERN_CDECL(int) nrv2e_decompress_safe_le16(const upx_byte *, ...);
|
||||
NRV_EXTERN_CDECL(int) nrv2e_decompress_safe_le32(const upx_byte *, ...);
|
||||
#elif defined(WITH_UCL)
|
||||
# if defined(UCL_USE_ASM)
|
||||
# include <ucl/ucl_asm.h>
|
||||
# define nrv2b_decompress_safe_8 ucl_nrv2b_decompress_asm_safe_8
|
||||
# define nrv2b_decompress_safe_le16 ucl_nrv2b_decompress_asm_safe_le16
|
||||
# define nrv2b_decompress_safe_le32 ucl_nrv2b_decompress_asm_safe_le32
|
||||
# define nrv2d_decompress_safe_8 ucl_nrv2d_decompress_asm_safe_8
|
||||
# define nrv2d_decompress_safe_le16 ucl_nrv2d_decompress_asm_safe_le16
|
||||
# define nrv2d_decompress_safe_le32 ucl_nrv2d_decompress_asm_safe_le32
|
||||
# define nrv2e_decompress_safe_8 ucl_nrv2e_decompress_asm_safe_8
|
||||
# define nrv2e_decompress_safe_le16 ucl_nrv2e_decompress_asm_safe_le16
|
||||
# define nrv2e_decompress_safe_le32 ucl_nrv2e_decompress_asm_safe_le32
|
||||
# else
|
||||
# define nrv2b_decompress_safe_8 ucl_nrv2b_decompress_safe_8
|
||||
# define nrv2b_decompress_safe_le16 ucl_nrv2b_decompress_safe_le16
|
||||
# define nrv2b_decompress_safe_le32 ucl_nrv2b_decompress_safe_le32
|
||||
# define nrv2d_decompress_safe_8 ucl_nrv2d_decompress_safe_8
|
||||
# define nrv2d_decompress_safe_le16 ucl_nrv2d_decompress_safe_le16
|
||||
# define nrv2d_decompress_safe_le32 ucl_nrv2d_decompress_safe_le32
|
||||
# define nrv2e_decompress_safe_8 ucl_nrv2e_decompress_safe_8
|
||||
# define nrv2e_decompress_safe_le16 ucl_nrv2e_decompress_safe_le16
|
||||
# define nrv2e_decompress_safe_le32 ucl_nrv2e_decompress_safe_le32
|
||||
# define upx_adler32 upx_adler32
|
||||
//# define upx_crc32 upx_crc32
|
||||
# define upx_compress upx_compress
|
||||
# define upx_decompress upx_decompress
|
||||
# if (UPX_VERSION_HEX >= 0x019000)
|
||||
# define upx_test_overlap upx_test_overlap
|
||||
# endif
|
||||
# include "compress.ch"
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
|
||||
#if 0 && defined(WITH_ZLIB) && defined(M_ZLIB)
|
||||
# include <zlib.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
||||
{
|
||||
if (len == 0)
|
||||
return adler;
|
||||
assert(buf != NULL);
|
||||
#if defined(WITH_NRV)
|
||||
return nrv_adler32(adler, (const nrv_byte *)buf, len);
|
||||
#elif defined(WITH_UCL)
|
||||
return ucl_adler32(adler, (const ucl_byte *)buf, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if (UPX_VERSION_HEX >= 0x019000)
|
||||
unsigned upx_adler32(unsigned adler, const void *buf, unsigned len)
|
||||
{
|
||||
return upx_adler32(buf, len, adler);
|
||||
}
|
||||
#endif /* UPX_VERSION_HEX */
|
||||
|
||||
|
||||
|
||||
#if 0 // NOT USED
|
||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
||||
{
|
||||
if (len == 0)
|
||||
return crc;
|
||||
assert(buf != NULL);
|
||||
#if defined(WITH_NRV)
|
||||
return nrv_crc32(crc, (const nrv_byte *)buf, len);
|
||||
#elif defined(WITH_UCL)
|
||||
return ucl_crc32(crc, (const ucl_byte *)buf, len);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_compress ( const upx_byte *src, upx_uint src_len,
|
||||
upx_byte *dst, upx_uint *dst_len,
|
||||
upx_progress_callback_t *cb,
|
||||
int method, int level,
|
||||
const struct upx_compress_config_t *conf_parm,
|
||||
upx_uintp result)
|
||||
{
|
||||
struct upx_compress_config_t conf;
|
||||
upx_uint result_buffer[16];
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
assert(level > 0);
|
||||
memset(&conf, 0xff, sizeof(conf));
|
||||
if (conf_parm)
|
||||
conf = *conf_parm; // struct copy
|
||||
if (!result)
|
||||
result = result_buffer;
|
||||
|
||||
// assume no info available - fill in worst case results
|
||||
//result[0] = 1; // min_offset_found - NOT USED
|
||||
result[1] = src_len - 1; // max_offset_found
|
||||
//result[2] = 2; // min_match_found - NOT USED
|
||||
result[3] = src_len - 1; // max_match_found
|
||||
//result[4] = 1; // min_run_found - NOT USED
|
||||
result[5] = src_len; // max_run_found
|
||||
result[6] = 1; // first_offset_found
|
||||
//result[7] = 999999; // same_match_offsets_found - NOT USED
|
||||
|
||||
#if 0 && defined(WITH_ZLIB) && defined(M_ZLIB)
|
||||
if (method == M_ZLIB)
|
||||
{
|
||||
uLong destLen = src_len + src_len / 8 + 256;
|
||||
r = compress2(dst, &destLen, src, src_len, UPX_MIN(level, 9));
|
||||
*dst_len = destLen;
|
||||
if (r == Z_MEM_ERROR)
|
||||
return UPX_E_OUT_OF_MEMORY;
|
||||
if (r != Z_OK)
|
||||
return UPX_E_ERROR;
|
||||
return UPX_E_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
// prepare bit-buffer settings
|
||||
conf.bb_endian = 0;
|
||||
conf.bb_size = 0;
|
||||
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16)
|
||||
{
|
||||
int n = (method - M_NRV2B_LE32) % 3;
|
||||
if (n == 0)
|
||||
conf.bb_size = 32;
|
||||
else if (n == 1)
|
||||
conf.bb_size = 8;
|
||||
else
|
||||
conf.bb_size = 16;
|
||||
}
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
|
||||
#if 1 && defined(WITH_NRV)
|
||||
if (level == 1 && conf.bb_size == 32 &&
|
||||
conf.max_offset >= src_len && conf.max_match >= src_len)
|
||||
{
|
||||
if (method == M_NRV2B_LE32)
|
||||
{
|
||||
upx_byte wrkmem[NRV2B_1_16_MEM_COMPRESS];
|
||||
#if defined(__UPX_CHECKER)
|
||||
memset(wrkmem,0,NRV2B_1_16_MEM_COMPRESS);
|
||||
#endif
|
||||
r = nrv2b_1_16_compress(src, src_len, dst, dst_len, wrkmem);
|
||||
}
|
||||
else if (method == M_NRV2D_LE32)
|
||||
{
|
||||
upx_byte wrkmem[NRV2D_1_16_MEM_COMPRESS];
|
||||
#if defined(__UPX_CHECKER)
|
||||
memset(wrkmem,0,NRV2D_1_16_MEM_COMPRESS);
|
||||
#endif
|
||||
r = nrv2d_1_16_compress(src, src_len, dst, dst_len, wrkmem);
|
||||
}
|
||||
#if 0
|
||||
else if (method == M_NRV2E_LE32)
|
||||
{
|
||||
upx_byte wrkmem[NRV2E_1_16_MEM_COMPRESS];
|
||||
#if defined(__UPX_CHECKER)
|
||||
memset(wrkmem,0,NRV2E_1_16_MEM_COMPRESS);
|
||||
#endif
|
||||
r = nrv2e_1_16_compress(src, src_len, dst, dst_len, wrkmem);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
// optimize compression parms
|
||||
if (level <= 3 && conf.max_offset == UPX_UINT_MAX)
|
||||
conf.max_offset = 8*1024-1;
|
||||
else if (level == 4 && conf.max_offset == UPX_UINT_MAX)
|
||||
conf.max_offset = 32*1024-1;
|
||||
#if defined(WITH_NRV)
|
||||
else if (level <= 6 && conf.max_offset == UPX_UINT_MAX)
|
||||
conf.max_offset = 1*1024*1024-1;
|
||||
else if (level <= 8 && conf.max_offset == UPX_UINT_MAX)
|
||||
conf.max_offset = 2*1024*1024-1;
|
||||
else if (level <= 10 && conf.max_offset == UPX_UINT_MAX)
|
||||
conf.max_offset = 4*1024*1024-1;
|
||||
#endif
|
||||
|
||||
if M_IS_NRV2B(method)
|
||||
r = nrv2b_99_compress_internal(src, src_len, dst, dst_len,
|
||||
cb, level, &conf, result);
|
||||
else if M_IS_NRV2D(method)
|
||||
r = nrv2d_99_compress_internal(src, src_len, dst, dst_len,
|
||||
cb, level, &conf, result);
|
||||
#if 0
|
||||
else if M_IS_NRV2E(method)
|
||||
r = nrv2e_99_compress_internal(src, src_len, dst, dst_len,
|
||||
cb, level, &conf, result);
|
||||
#endif
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_decompress ( const upx_byte *src, upx_uint src_len,
|
||||
upx_byte *dst, upx_uint *dst_len,
|
||||
int method )
|
||||
{
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
#if 0 && defined(WITH_ZLIB) && defined(M_ZLIB)
|
||||
if (method == M_ZLIB)
|
||||
{
|
||||
uLong destLen = *dst_len;
|
||||
r = uncompress(dst, &destLen, src, src_len);
|
||||
*dst_len = destLen;
|
||||
if (r == Z_MEM_ERROR)
|
||||
return UPX_E_OUT_OF_MEMORY;
|
||||
if (r != Z_OK)
|
||||
return UPX_E_ERROR;
|
||||
return UPX_E_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case M_NRV2B_8:
|
||||
r = nrv2b_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = nrv2b_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = nrv2b_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = nrv2d_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = nrv2d_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
#if 0
|
||||
case M_NRV2E_8:
|
||||
r = nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = nrv2e_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if (UPX_VERSION_HEX >= 0x019000)
|
||||
|
||||
int upx_test_overlap ( const upx_byte *buf, upx_uint src_off,
|
||||
upx_uint src_len, upx_uint *dst_len,
|
||||
int method )
|
||||
{
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
#if 0
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif /* UPX_VERSION_HEX */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
|
||||
244
src/conf.h
244
src/conf.h
@ -36,10 +36,39 @@
|
||||
#if defined(UPX_CONFIG_H)
|
||||
# include UPX_CONFIG_H
|
||||
#endif
|
||||
#include <limits.h>
|
||||
|
||||
#if defined(HAVE_STDINT_H)
|
||||
# if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
# endif
|
||||
# if !defined(__STDC_CONSTANT_MACROS)
|
||||
# define __STDC_CONSTANT_MACROS 1
|
||||
# endif
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include "version.h"
|
||||
#include "tailor.h"
|
||||
|
||||
// upx_int64l is int_least64_t in <stdint.h> terminology
|
||||
#if !defined(upx_int64l)
|
||||
# if defined(HAVE_STDINT_H)
|
||||
# define upx_int64l int_least64_t
|
||||
# define upx_uint64l uint_least64_t
|
||||
# elif (ULONG_MAX > 0xffffffffL)
|
||||
# define upx_int64l long int
|
||||
# define upx_uint64l unsigned long int
|
||||
# elif defined(__GNUC__) || defined(__DMC__)
|
||||
# define upx_int64l long long int
|
||||
# define upx_uint64l unsigned long long int
|
||||
# elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__WATCOMC__)
|
||||
# define upx_int64l __int64
|
||||
# define upx_uint64l unsigned __int64
|
||||
# else
|
||||
# error "need a 64-bit integer type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(__i386__)
|
||||
# if defined(__386__) || defined(_M_IX86)
|
||||
# define __i386__ 1
|
||||
@ -58,25 +87,8 @@
|
||||
#undef unix
|
||||
|
||||
|
||||
#if defined(WITH_NRV)
|
||||
# include <nrv/nrvconf.h>
|
||||
# if !defined(UPX_UINT_MAX)
|
||||
# define UPX_UINT_MAX NRV_UINT_MAX
|
||||
# define upx_uint nrv_uint
|
||||
# define upx_voidp nrv_voidp
|
||||
# define upx_uintp nrv_uintp
|
||||
# define upx_byte nrv_byte
|
||||
# define upx_bytep nrv_bytep
|
||||
# define upx_bool nrv_bool
|
||||
# define upx_progress_callback_t nrv_progress_callback_t
|
||||
# define UPX_E_OK NRV_E_OK
|
||||
# define UPX_E_ERROR NRV_E_ERROR
|
||||
# define UPX_E_OUT_OF_MEMORY NRV_E_OUT_OF_MEMORY
|
||||
# define __UPX_ENTRY __NRV_ENTRY
|
||||
# endif
|
||||
# if 1 && defined(__i386__) && !defined(__BORLANDC__) && !defined(__DMC__)
|
||||
# define NRV_USE_ASM
|
||||
# endif
|
||||
#if !defined(WITH_UCL)
|
||||
# error "you lose"
|
||||
#endif
|
||||
#if defined(WITH_UCL)
|
||||
# include <ucl/uclconf.h>
|
||||
@ -92,6 +104,7 @@
|
||||
# define upx_byte ucl_byte
|
||||
# define upx_bytep ucl_bytep
|
||||
# define upx_bool ucl_bool
|
||||
# define upx_compress_config_t ucl_compress_config_t
|
||||
# define upx_progress_callback_t ucl_progress_callback_t
|
||||
# define UPX_E_OK UCL_E_OK
|
||||
# define UPX_E_ERROR UCL_E_ERROR
|
||||
@ -99,21 +112,17 @@
|
||||
# define __UPX_ENTRY __UCL_ENTRY
|
||||
# endif
|
||||
#endif
|
||||
#if defined(WITH_NRV)
|
||||
# include <nrv/nrvconf.h>
|
||||
#endif
|
||||
#if !defined(__UPX_CHECKER)
|
||||
# if defined(__UCL_CHECKER) || defined(__NRV_CHECKER)
|
||||
# define __UPX_CHECKER
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(UPX_UINT_MAX) || (UINT_MAX < 0xffffffffL)
|
||||
#if !defined(UINT_MAX) || (UINT_MAX < 0xffffffffL)
|
||||
# error "you lose"
|
||||
#endif
|
||||
#if !defined(WITH_UCL)
|
||||
# error "you lose"
|
||||
#endif
|
||||
|
||||
#ifndef WITH_ZLIB
|
||||
# define WITH_ZLIB 1
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@ -177,7 +186,9 @@
|
||||
|
||||
|
||||
// malloc debuggers
|
||||
#if defined(WITH_DMALLOC)
|
||||
#if defined(WITH_VALGRIND)
|
||||
# include <valgrind.h>
|
||||
#elif defined(WITH_DMALLOC)
|
||||
# define DMALLOC_FUNC_CHECK
|
||||
# include <dmalloc.h>
|
||||
#elif defined(WITH_GC)
|
||||
@ -189,9 +200,20 @@
|
||||
# define malloc GC_MALLOC
|
||||
# define realloc GC_REALLOC
|
||||
# define free GC_FREE
|
||||
#elif defined(WITH_MSS)
|
||||
# define MSS
|
||||
# include <mss.h>
|
||||
#endif
|
||||
|
||||
#if !defined(VALGRIND_MAKE_WRITABLE)
|
||||
# define VALGRIND_MAKE_WRITABLE(addr,len) 0
|
||||
#endif
|
||||
#if !defined(VALGRIND_MAKE_READABLE)
|
||||
# if 0
|
||||
# define VALGRIND_MAKE_READABLE(addr,len) memset(addr,0,len), 0
|
||||
# else
|
||||
# define VALGRIND_MAKE_READABLE(addr,len) 0
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(VALGRIND_DISCARD)
|
||||
# define VALGRIND_DISCARD(handle) ((void) &handle)
|
||||
#endif
|
||||
|
||||
|
||||
@ -210,10 +232,6 @@
|
||||
(__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
|
||||
#endif
|
||||
|
||||
#if defined(NO_BOOL)
|
||||
typedef int bool;
|
||||
enum { false, true };
|
||||
#endif
|
||||
|
||||
#if !defined(PATH_MAX)
|
||||
# define PATH_MAX 512
|
||||
@ -231,6 +249,7 @@ enum { false, true };
|
||||
#endif
|
||||
typedef RETSIGTYPE (SIGTYPEENTRY *sig_type)(int);
|
||||
|
||||
|
||||
#undef MODE_T
|
||||
#if defined(HAVE_MODE_T)
|
||||
# define MODE_T mode_t
|
||||
@ -238,6 +257,7 @@ typedef RETSIGTYPE (SIGTYPEENTRY *sig_type)(int);
|
||||
# define MODE_T int
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(HAVE_STRCASECMP)
|
||||
# if defined(HAVE_STRICMP)
|
||||
# define strcasecmp stricmp
|
||||
@ -341,10 +361,11 @@ typedef RETSIGTYPE (SIGTYPEENTRY *sig_type)(int);
|
||||
#endif
|
||||
|
||||
|
||||
#undef NOTHROW
|
||||
#if defined(__cplusplus)
|
||||
#define NOTHROW throw()
|
||||
# define NOTHROW throw()
|
||||
#else
|
||||
#define NOTHROW
|
||||
# define NOTHROW
|
||||
#endif
|
||||
|
||||
|
||||
@ -436,17 +457,10 @@ inline void operator delete[](void *p)
|
||||
// gets destructed when leaving scope or on exceptions.
|
||||
// "var" is declared as a read-only reference to a pointer
|
||||
// and behaves exactly like an array "var[]".
|
||||
#if 0
|
||||
# define Array(type, var, size) \
|
||||
#define Array(type, var, size) \
|
||||
assert((int)(size) > 0); \
|
||||
std::vector<type> var ## _array_vec((size)); \
|
||||
type * const & var = & var ## _array_vec[0]
|
||||
#else
|
||||
# define Array(type, var, size) \
|
||||
assert((int)(size) > 0); \
|
||||
MemBuffer var ## _array_buf((size)*(sizeof(type))); \
|
||||
type * const & var = ((type *) var ## _array_buf.getVoidPtr())
|
||||
#endif
|
||||
MemBuffer var ## _membuf((size)*(sizeof(type))); \
|
||||
type * const & var = ((type *) var ## _membuf.getVoidPtr())
|
||||
|
||||
#define ByteArray(var, size) Array(unsigned char, var, size)
|
||||
|
||||
@ -516,111 +530,17 @@ inline void operator delete[](void *p)
|
||||
// globals
|
||||
**************************************************************************/
|
||||
|
||||
// options - command
|
||||
enum {
|
||||
CMD_NONE,
|
||||
CMD_COMPRESS, CMD_DECOMPRESS, CMD_TEST, CMD_LIST, CMD_FILEINFO,
|
||||
CMD_HELP, CMD_LICENSE, CMD_VERSION
|
||||
};
|
||||
|
||||
#include "snprintf.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
#include "stdcxx.h"
|
||||
#include "options.h"
|
||||
#include "except.h"
|
||||
#include "bele.h"
|
||||
#include "util.h"
|
||||
#include "console.h"
|
||||
|
||||
struct options_t {
|
||||
int cmd;
|
||||
|
||||
// compression options
|
||||
int method;
|
||||
int level; // compression level 1..10
|
||||
int filter; // preferred filter from Packer::getFilters()
|
||||
bool all_methods; // try all available compression methods ?
|
||||
bool all_filters; // try all available filters ?
|
||||
|
||||
// other options
|
||||
int backup;
|
||||
int console;
|
||||
int debug;
|
||||
int force;
|
||||
int info_mode;
|
||||
bool ignorewarn;
|
||||
bool no_env;
|
||||
bool no_progress;
|
||||
const char *output_name;
|
||||
int small;
|
||||
int verbose;
|
||||
bool to_stdout;
|
||||
|
||||
// overlay handling
|
||||
enum {
|
||||
SKIP_OVERLAY = 0,
|
||||
COPY_OVERLAY = 1,
|
||||
STRIP_OVERLAY = 2
|
||||
};
|
||||
int overlay;
|
||||
|
||||
// compression runtime parameters - see struct ucl_compress_config_t
|
||||
struct {
|
||||
upx_uint max_offset;
|
||||
upx_uint max_match;
|
||||
int s_level;
|
||||
int h_level;
|
||||
int p_level;
|
||||
int c_flags;
|
||||
upx_uint m_size;
|
||||
} crp;
|
||||
|
||||
// CPU
|
||||
enum {
|
||||
CPU_DEFAULT = 0,
|
||||
CPU_8086 = 1,
|
||||
CPU_286 = 2,
|
||||
CPU_386 = 3,
|
||||
CPU_486 = 4,
|
||||
CPU_586 = 5,
|
||||
CPU_686 = 6
|
||||
};
|
||||
int cpu;
|
||||
|
||||
// options for various executable formats
|
||||
struct {
|
||||
bool force_stub;
|
||||
bool no_reloc;
|
||||
} dos;
|
||||
struct {
|
||||
bool coff;
|
||||
} djgpp2;
|
||||
struct {
|
||||
unsigned no_align;
|
||||
} psx;
|
||||
struct {
|
||||
bool split_segments;
|
||||
} tos;
|
||||
struct {
|
||||
unsigned blocksize;
|
||||
bool force_execve; // force the linux/386 execve format
|
||||
enum { SCRIPT_MAX = 32 };
|
||||
const char *script_name;
|
||||
} unix;
|
||||
struct {
|
||||
bool le;
|
||||
} wcle;
|
||||
struct {
|
||||
int compress_exports;
|
||||
int compress_icons;
|
||||
int compress_resources;
|
||||
signed char compress_rt[25]; // 25 == RT_LAST
|
||||
int strip_relocs;
|
||||
} w32pe;
|
||||
};
|
||||
|
||||
extern struct options_t * volatile opt;
|
||||
|
||||
|
||||
// main.cpp
|
||||
extern const char *progname;
|
||||
@ -679,40 +599,22 @@ void show_version(int);
|
||||
|
||||
// compress.cpp
|
||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
|
||||
unsigned upx_adler32(unsigned adler, const void *buf, unsigned len);
|
||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc=0);
|
||||
|
||||
#if defined(WITH_NRV)
|
||||
struct nrv_compress_config_t;
|
||||
struct nrv_compress_config_t
|
||||
{
|
||||
int bb_endian;
|
||||
int bb_size;
|
||||
nrv_uint max_offset;
|
||||
nrv_uint max_match;
|
||||
int s_level;
|
||||
int h_level;
|
||||
int p_level;
|
||||
int c_flags;
|
||||
nrv_uint m_size;
|
||||
};
|
||||
#define upx_compress_config_t nrv_compress_config_t
|
||||
#elif defined(WITH_UCL)
|
||||
#define upx_compress_config_t ucl_compress_config_t
|
||||
#endif
|
||||
|
||||
int upx_compress ( const upx_byte *src, upx_uint src_len,
|
||||
upx_byte *dst, upx_uint *dst_len,
|
||||
int upx_compress ( const upx_bytep src, upx_uint src_len,
|
||||
upx_bytep dst, upx_uintp dst_len,
|
||||
upx_progress_callback_t *cb,
|
||||
int method, int level,
|
||||
const struct upx_compress_config_t *conf,
|
||||
upx_uintp result);
|
||||
int upx_decompress ( const upx_byte *src, upx_uint src_len,
|
||||
upx_byte *dst, upx_uint *dst_len,
|
||||
upx_uintp result );
|
||||
int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
||||
upx_bytep dst, upx_uintp dst_len,
|
||||
int method );
|
||||
int upx_test_overlap ( const upx_byte *buf, upx_uint src_off,
|
||||
upx_uint src_len, upx_uint *dst_len,
|
||||
int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
||||
upx_uint src_len, upx_uintp dst_len,
|
||||
int method );
|
||||
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
|
||||
@ -29,12 +29,6 @@
|
||||
/* Define to `long' if <stddef.h> doesn't define. */
|
||||
/* #undef ptrdiff_t */
|
||||
|
||||
/* The number of bytes in a ptrdiff_t. */
|
||||
#define SIZEOF_PTRDIFF_T 4
|
||||
|
||||
/* The number of bytes in a size_t. */
|
||||
#define SIZEOF_SIZE_T 4
|
||||
|
||||
/* Define when using the dmalloc package. */
|
||||
/* #undef WITH_DMALLOC */
|
||||
|
||||
@ -179,6 +173,9 @@
|
||||
/* Define if you have the <stddef.h> header file. */
|
||||
#define HAVE_STDDEF_H 1
|
||||
|
||||
/* Define if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
@ -225,14 +222,6 @@
|
||||
# undef /**/ HAVE_SYS_TIMES_H
|
||||
#endif
|
||||
|
||||
#if (SIZEOF_PTRDIFF_T <= 0)
|
||||
# undef /**/ SIZEOF_PTRDIFF_T
|
||||
#endif
|
||||
|
||||
#if (SIZEOF_SIZE_T <= 0)
|
||||
# undef /**/ SIZEOF_SIZE_T
|
||||
#endif
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/*
|
||||
|
||||
226
src/config_h/sparc_sun_solaris28.h
Normal file
226
src/config_h/sparc_sun_solaris28.h
Normal file
@ -0,0 +1,226 @@
|
||||
/* pseudo <config.h> for sparc-sun-solaris2.8 */
|
||||
|
||||
#ifndef __UPX_CONFIG_H
|
||||
#define __UPX_CONFIG_H
|
||||
|
||||
/* $TOP$ */
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef NO_MINUS_C_MINUS_O */
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||
/* #undef size_t */
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Define if your memcmp is broken. */
|
||||
/* #undef NO_MEMCMP */
|
||||
|
||||
/* Define to `long' if <stddef.h> doesn't define. */
|
||||
/* #undef ptrdiff_t */
|
||||
|
||||
/* Define when using the dmalloc package. */
|
||||
/* #undef WITH_DMALLOC */
|
||||
|
||||
/* Define if you have the access function. */
|
||||
#define HAVE_ACCESS 1
|
||||
|
||||
/* Define if you have the atoi function. */
|
||||
#define HAVE_ATOI 1
|
||||
|
||||
/* Define if you have the chmod function. */
|
||||
#define HAVE_CHMOD 1
|
||||
|
||||
/* Define if you have the chown function. */
|
||||
#define HAVE_CHOWN 1
|
||||
|
||||
/* Define if you have the ctime function. */
|
||||
#define HAVE_CTIME 1
|
||||
|
||||
/* Define if you have the difftime function. */
|
||||
#define HAVE_DIFFTIME 1
|
||||
|
||||
/* Define if you have the fchmod function. */
|
||||
#define HAVE_FCHMOD 1
|
||||
|
||||
/* Define if you have the fileno function. */
|
||||
#define HAVE_FILENO 1
|
||||
|
||||
/* Define if you have the fstat function. */
|
||||
#define HAVE_FSTAT 1
|
||||
|
||||
/* Define if you have the XXX function. */
|
||||
#define HAVE_GETPID 1
|
||||
|
||||
/* Define if you have the XXX function. */
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define if you have the getumask function. */
|
||||
/* #undef HAVE_GETUMASK */
|
||||
|
||||
/* Define if you have the gmtime function. */
|
||||
#define HAVE_GMTIME 1
|
||||
|
||||
/* Define if you have the index function. */
|
||||
#define HAVE_INDEX 1
|
||||
|
||||
/* Define if you have the isatty function. */
|
||||
#define HAVE_ISATTY 1
|
||||
|
||||
/* Define if you have the lstat function. */
|
||||
#define HAVE_LSTAT 1
|
||||
|
||||
/* Define if you have the localtime function. */
|
||||
#define HAVE_LOCALTIME 1
|
||||
|
||||
/* Define if you have the memcmp function. */
|
||||
#define HAVE_MEMCMP 1
|
||||
|
||||
/* Define if you have the memcpy function. */
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
/* Define if you have the memmove function. */
|
||||
#define HAVE_MEMMOVE 1
|
||||
|
||||
/* Define if you have the memset function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define if you have the mktime function. */
|
||||
#define HAVE_MKTIME 1
|
||||
|
||||
/* Define if you have the setmode function. */
|
||||
/* #undef HAVE_SETMODE */
|
||||
|
||||
/* Define if you have the stat function. */
|
||||
#define HAVE_STAT 1
|
||||
|
||||
/* Define if you have the strcasecmp function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define if you have the strchr function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define if you have the strdup function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define if you have the strftime function. */
|
||||
#define HAVE_STRFTIME 1
|
||||
|
||||
/* Define if you have the stricmp function. */
|
||||
/* #undef HAVE_STRICMP */
|
||||
|
||||
/* Define if you have the strncasecmp function. */
|
||||
#define HAVE_STRNCASECMP 1
|
||||
|
||||
/* Define if you have the strnicmp function. */
|
||||
/* #undef HAVE_STRNICMP */
|
||||
|
||||
/* Define if you have the strstr function. */
|
||||
#define HAVE_STRSTR 1
|
||||
|
||||
/* Define if you have the tzset function. */
|
||||
#define HAVE_TZSET 1
|
||||
|
||||
/* Define if you have the umask function. */
|
||||
#define HAVE_UMASK 1
|
||||
|
||||
/* Define if you have the utime function. */
|
||||
#define HAVE_UTIME 1
|
||||
|
||||
/* Define if you have the vsnprintf function. */
|
||||
#define HAVE_VSNPRINTF 1
|
||||
|
||||
/* Define if you have the <assert.h> header file. */
|
||||
#define HAVE_ASSERT_H 1
|
||||
|
||||
/* Define if you have the <ctype.h> header file. */
|
||||
#define HAVE_CTYPE_H 1
|
||||
|
||||
/* Define if you have the <curses.h> header file. */
|
||||
#define HAVE_CURSES_H 1
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define if you have the <linux/kd.h> header file. */
|
||||
#define HAVE_LINUX_KD_H 1
|
||||
|
||||
/* Define if you have the <linux/kdev_t.h> header file. */
|
||||
#define HAVE_LINUX_KDEV_T_H 1
|
||||
|
||||
/* Define if you have the <linux/major.h> header file. */
|
||||
#define HAVE_LINUX_MAJOR_H 1
|
||||
|
||||
/* Define if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define if you have the <ncurses.h> header file. */
|
||||
#define HAVE_NCURSES_H 1
|
||||
|
||||
/* Define if you have the <signal.h> header file. */
|
||||
#define HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define if you have the <stddef.h> header file. */
|
||||
#define HAVE_STDDEF_H 1
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define if you have the <sys/resource.h> header file. */
|
||||
#define HAVE_SYS_RESOURCE_H 1
|
||||
|
||||
/* Define if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define if you have the <sys/times.h> header file. */
|
||||
#define HAVE_SYS_TIMES_H 1
|
||||
|
||||
/* Define if you have the <sys/utime.h> header file. */
|
||||
/* #undef HAVE_SYS_UTIME_H */
|
||||
|
||||
/* Define if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define if you have the <utime.h> header file. */
|
||||
#define HAVE_UTIME_H 1
|
||||
|
||||
/* $BOTTOM$ */
|
||||
|
||||
#if defined(HAVE_GMTIME) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_GMTIME
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LOCALTIME) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_LOCALTIME
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_STRFTIME) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_STRFTIME
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_RESOURCE_H) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_SYS_RESOURCE_H
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_TIMES_H) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_SYS_TIMES_H
|
||||
#endif
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/*
|
||||
vi:ts=4
|
||||
*/
|
||||
@ -120,6 +120,7 @@ public:
|
||||
|
||||
off_t getBytesWritten() const { return bytes_written; }
|
||||
|
||||
#if (UPX_VERSION_HEX >= 0x019000)
|
||||
// FIXME - these won't work when using the `--stdout' option
|
||||
virtual void seek(off_t off, int whence)
|
||||
{
|
||||
@ -132,6 +133,7 @@ public:
|
||||
write(buf, len);
|
||||
bytes_written -= len; // restore
|
||||
}
|
||||
#endif
|
||||
|
||||
// util
|
||||
static void dump(const char *name, const void *buf, int len, int flags=-1);
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#include "filter/sub.hh"
|
||||
#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)
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#include "filter/sub.hh"
|
||||
#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)
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#include "filter/sub.hh"
|
||||
#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)
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2001 Laszlo Molnar
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@ -21,13 +21,12 @@
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
|
||||
26
src/main.cpp
26
src/main.cpp
@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2001 Laszlo Molnar
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@ -21,13 +21,12 @@
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "version.h"
|
||||
#include "mygetopt.h"
|
||||
#include "file.h"
|
||||
#include "packer.h"
|
||||
@ -505,6 +504,10 @@ static int do_option(int optc, const char *arg)
|
||||
if (!set_method(M_NRV2D_LE32, -1))
|
||||
e_method(M_NRV2D_LE32, opt->level);
|
||||
break;
|
||||
case 705:
|
||||
if (!set_method(M_NRV2E_LE32, -1))
|
||||
e_method(M_NRV2E_LE32, opt->level);
|
||||
break;
|
||||
|
||||
// compression level
|
||||
case '1':
|
||||
@ -766,12 +769,9 @@ static const struct mfx_option longopts[] =
|
||||
{"color", 0, 0, 514},
|
||||
|
||||
// compression method
|
||||
{"2b", 0x10, 0, 702}, // --2b
|
||||
{"n2b", 0x10, 0, 702}, // --n2b
|
||||
{"nrv2b", 0x10, 0, 702}, // --nrv2b
|
||||
{"2d", 0x10, 0, 704}, // --2d
|
||||
{"n2d", 0x10, 0, 704}, // --n2d
|
||||
{"nrv2d", 0x10, 0, 704}, // --nrv2d
|
||||
{"nrv2e", 0x10, 0, 705}, // --nrv2e
|
||||
// compression settings
|
||||
{"all-filters", 0x10, 0, 523},
|
||||
{"all-methods", 0x10, 0, 524},
|
||||
@ -1002,6 +1002,10 @@ void upx_sanity_check(void)
|
||||
COMPILE_TIME_ASSERT(sizeof(void *) >= 4);
|
||||
COMPILE_TIME_ASSERT(sizeof(long) >= sizeof(void *));
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(upx_int64l) >= 8);
|
||||
COMPILE_TIME_ASSERT(sizeof(upx_int64l) >= sizeof(long));
|
||||
COMPILE_TIME_ASSERT(sizeof(upx_int64l) == sizeof(upx_uint64l));
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(off_t) >= sizeof(long));
|
||||
COMPILE_TIME_ASSERT(((off_t) -1) < 0);
|
||||
COMPILE_TIME_ASSERT(sizeof(ptrdiff_t) >= sizeof(int));
|
||||
@ -1112,10 +1116,6 @@ int main(int argc, char *argv[])
|
||||
upx_sanity_check();
|
||||
init_options(opt);
|
||||
|
||||
#if defined(WITH_MSS)
|
||||
MSS_DISABLE_LOG_OUTPUT;
|
||||
#endif
|
||||
|
||||
if (!argv[0] || !argv[0][0])
|
||||
argv[0] = default_argv0;
|
||||
argv0 = argv[0];
|
||||
|
||||
141
src/options.h
Normal file
141
src/options.h
Normal file
@ -0,0 +1,141 @@
|
||||
/* options.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_OPTIONS_H
|
||||
#define __UPX_OPTIONS_H
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// globals
|
||||
**************************************************************************/
|
||||
|
||||
// options - command
|
||||
enum {
|
||||
CMD_NONE,
|
||||
CMD_COMPRESS, CMD_DECOMPRESS, CMD_TEST, CMD_LIST, CMD_FILEINFO,
|
||||
CMD_HELP, CMD_LICENSE, CMD_VERSION
|
||||
};
|
||||
|
||||
|
||||
struct options_t {
|
||||
int cmd;
|
||||
|
||||
// compression options
|
||||
int method;
|
||||
int level; // compression level 1..10
|
||||
int filter; // preferred filter from Packer::getFilters()
|
||||
bool all_methods; // try all available compression methods ?
|
||||
bool all_filters; // try all available filters ?
|
||||
|
||||
// other options
|
||||
int backup;
|
||||
int console;
|
||||
int debug;
|
||||
int force;
|
||||
int info_mode;
|
||||
bool ignorewarn;
|
||||
bool no_env;
|
||||
bool no_progress;
|
||||
const char *output_name;
|
||||
int small;
|
||||
int verbose;
|
||||
bool to_stdout;
|
||||
|
||||
// overlay handling
|
||||
enum {
|
||||
SKIP_OVERLAY = 0,
|
||||
COPY_OVERLAY = 1,
|
||||
STRIP_OVERLAY = 2
|
||||
};
|
||||
int overlay;
|
||||
|
||||
// compression runtime parameters - see struct ucl_compress_config_t
|
||||
struct {
|
||||
upx_uint max_offset;
|
||||
upx_uint max_match;
|
||||
int s_level;
|
||||
int h_level;
|
||||
int p_level;
|
||||
int c_flags;
|
||||
upx_uint m_size;
|
||||
} crp;
|
||||
|
||||
// CPU
|
||||
enum {
|
||||
CPU_DEFAULT = 0,
|
||||
CPU_8086 = 1,
|
||||
CPU_286 = 2,
|
||||
CPU_386 = 3,
|
||||
CPU_486 = 4,
|
||||
CPU_586 = 5,
|
||||
CPU_686 = 6
|
||||
};
|
||||
int cpu;
|
||||
|
||||
// options for various executable formats
|
||||
struct {
|
||||
bool force_stub;
|
||||
bool no_reloc;
|
||||
} dos;
|
||||
struct {
|
||||
bool coff;
|
||||
} djgpp2;
|
||||
struct {
|
||||
bool no_align;
|
||||
} psx;
|
||||
struct {
|
||||
bool split_segments;
|
||||
} tos;
|
||||
struct {
|
||||
unsigned blocksize;
|
||||
bool force_execve; // force the linux/386 execve format
|
||||
enum { SCRIPT_MAX = 32 };
|
||||
const char *script_name;
|
||||
} unix;
|
||||
struct {
|
||||
bool le;
|
||||
} wcle;
|
||||
struct {
|
||||
int compress_exports;
|
||||
int compress_icons;
|
||||
int compress_resources;
|
||||
signed char compress_rt[25]; // 25 == RT_LAST
|
||||
int strip_relocs;
|
||||
} w32pe;
|
||||
};
|
||||
|
||||
extern struct options_t * volatile opt;
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
@ -164,7 +164,7 @@ void PackLinuxI386elf::packExtent(
|
||||
// compressWithFilters() updates u_adler _inside_ compress();
|
||||
// that is, AFTER filtering. We want BEFORE filtering,
|
||||
// so that decompression checks the end-to-end checksum.
|
||||
end_u_adler = upx_adler32(ph.u_adler, ibuf, ph.u_len);
|
||||
end_u_adler = upx_adler32(ibuf, ph.u_len, ph.u_adler);
|
||||
ft->buf_len = l;
|
||||
compressWithFilters(ft, OVERHEAD, strategy);
|
||||
}
|
||||
@ -181,7 +181,7 @@ void PackLinuxI386elf::packExtent(
|
||||
else {
|
||||
ph. c_len = ph.u_len;
|
||||
// must update checksum of compressed data
|
||||
ph.c_adler = upx_adler32(ph.c_adler, ibuf, ph.u_len);
|
||||
ph.c_adler = upx_adler32(ibuf, ph.u_len, ph.c_adler);
|
||||
}
|
||||
|
||||
// write block sizes
|
||||
@ -338,7 +338,7 @@ void PackLinuxI386elf::unpackExtent(unsigned wanted, OutputFile *fo,
|
||||
int j = blocksize + OVERHEAD - sz_cpr;
|
||||
fi->readx(ibuf+j, sz_cpr);
|
||||
// update checksum of compressed data
|
||||
c_adler = upx_adler32(c_adler, ibuf + j, sz_cpr);
|
||||
c_adler = upx_adler32(ibuf + j, sz_cpr, c_adler);
|
||||
// decompress
|
||||
if (sz_cpr < sz_unc)
|
||||
{
|
||||
@ -355,7 +355,7 @@ void PackLinuxI386elf::unpackExtent(unsigned wanted, OutputFile *fo,
|
||||
j = 0;
|
||||
}
|
||||
// update checksum of uncompressed data
|
||||
u_adler = upx_adler32(u_adler, ibuf + j, sz_unc);
|
||||
u_adler = upx_adler32(ibuf + j, sz_unc, u_adler);
|
||||
total_in += sz_cpr;
|
||||
total_out += sz_unc;
|
||||
// write block
|
||||
|
||||
@ -54,7 +54,7 @@ const upx_byte *PackLinuxI386sep::getLoader() const
|
||||
if (0==name) {
|
||||
name = "/usr/local/lib/upxX";
|
||||
}
|
||||
sprintf(script, "#!%s\n", name);
|
||||
upx_snprintf(script, sizeof(script), "#!%s\n", name);
|
||||
if (M_IS_NRV2B(ph.method)) {
|
||||
script[strlen(script)-2] = 'b';
|
||||
return (upx_byte const *)script;
|
||||
|
||||
@ -30,7 +30,6 @@
|
||||
#include "filter.h"
|
||||
#include "packer.h"
|
||||
#include "p_psx.h"
|
||||
#include "version.h"
|
||||
|
||||
static const
|
||||
#include "stub/l_psx.h"
|
||||
|
||||
@ -640,7 +640,7 @@ int PackTos::canUnpack()
|
||||
{
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
if (!readPackHeader(512))
|
||||
if (!readPackHeader(768))
|
||||
return false;
|
||||
// check header as set by packer
|
||||
if ((ih.fh_text & 3) != 0 || (ih.fh_data & 3) != 0 || (ih.fh_bss & 3) != 0
|
||||
|
||||
@ -158,7 +158,7 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
|
||||
// compressWithFilters() updates u_adler _inside_ compress();
|
||||
// that is, AFTER filtering. We want BEFORE filtering,
|
||||
// so that decompression checks the end-to-end checksum.
|
||||
unsigned const end_u_adler = upx_adler32(ph.u_adler, ibuf, ph.u_len);
|
||||
unsigned const end_u_adler = upx_adler32(ibuf, ph.u_len, ph.u_adler);
|
||||
compressWithFilters(&ft, OVERHEAD, strategy);
|
||||
|
||||
if (ph.c_len < ph.u_len) {
|
||||
@ -170,7 +170,7 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
|
||||
// block is not compressible
|
||||
ph.c_len = ph.u_len;
|
||||
// must manually update checksum of compressed data
|
||||
ph.c_adler = upx_adler32(ph.c_adler, ibuf, ph.u_len);
|
||||
ph.c_adler = upx_adler32(ibuf, ph.u_len, ph.c_adler);
|
||||
}
|
||||
|
||||
// write block header
|
||||
@ -370,7 +370,7 @@ void PackUnix::unpack(OutputFile *fo)
|
||||
i = blocksize + OVERHEAD - sz_cpr;
|
||||
fi->readx(buf+i, sz_cpr);
|
||||
// update checksum of compressed data
|
||||
c_adler = upx_adler32(c_adler, buf + i, sz_cpr);
|
||||
c_adler = upx_adler32(buf + i, sz_cpr, c_adler);
|
||||
// decompress
|
||||
if (sz_cpr < sz_unc) {
|
||||
decompress(buf+i, buf, false);
|
||||
@ -383,7 +383,7 @@ void PackUnix::unpack(OutputFile *fo)
|
||||
i = 0;
|
||||
}
|
||||
// update checksum of uncompressed data
|
||||
u_adler = upx_adler32(u_adler, buf + i, sz_unc);
|
||||
u_adler = upx_adler32(buf + i, sz_unc, u_adler);
|
||||
total_in += sz_cpr;
|
||||
total_out += sz_unc;
|
||||
// write block
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2001 Laszlo Molnar
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@ -21,8 +21,8 @@
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
@ -283,7 +283,7 @@ void PackWcle::preprocessFixups()
|
||||
for (ic = jc = 0; ic < objects; ic++)
|
||||
jc += counts[ic];
|
||||
|
||||
ByteArray(rl,jc);
|
||||
ByteArray(rl, jc);
|
||||
ByteArray(srf, counts[objects+0]+1);
|
||||
ByteArray(slf, counts[objects+1]+1);
|
||||
|
||||
@ -296,7 +296,7 @@ void PackWcle::preprocessFixups()
|
||||
{
|
||||
while ((unsigned)(fix - ifixups) < get_le32(ifpage_table+ic+1))
|
||||
{
|
||||
const signed short fixp2 = (signed short) get_le16(fix+2);
|
||||
const int fixp2 = get_le16_signed(fix+2);
|
||||
unsigned value;
|
||||
|
||||
switch (*fix)
|
||||
@ -318,7 +318,7 @@ void PackWcle::preprocessFixups()
|
||||
fix += 5;
|
||||
break;
|
||||
case 5: // 16-bit offset
|
||||
if ((unsigned short)fixp2 < 4096 && IOT(fix[4]-1,my_base_address) == jc)
|
||||
if ((unsigned)fixp2 < 4096 && IOT(fix[4]-1,my_base_address) == jc)
|
||||
dputc('6',stdout);
|
||||
else
|
||||
throwCantPack("unsupported 16-bit offset relocation");
|
||||
@ -461,7 +461,8 @@ void PackWcle::pack(OutputFile *fo)
|
||||
readImage();
|
||||
readNonResidentNames();
|
||||
|
||||
if (find_le32(iimage,20,get_le32("UPX ")) >= 0)
|
||||
// if (find_le32(iimage,20,get_le32("UPX ")) >= 0)
|
||||
if (find_le32(iimage,UPX_MIN(soimage,256u),UPX_MAGIC_LE32) >= 0)
|
||||
throwAlreadyPacked();
|
||||
|
||||
if (ih.init_ss_object != objects)
|
||||
@ -546,7 +547,7 @@ void PackWcle::pack(OutputFile *fo)
|
||||
|
||||
// copy the overlay
|
||||
const unsigned overlaystart = ih.data_pages_offset + exe_offset
|
||||
+ mps * (pages - 1) + ih.bytes_on_last_page;
|
||||
+ getImageSize();
|
||||
const unsigned overlay = file_size - overlaystart - ih.non_resident_name_table_length;
|
||||
checkOverlay(overlay);
|
||||
copyOverlay(fo, overlay, &oimage);
|
||||
@ -762,7 +763,9 @@ int PackWcle::canUnpack()
|
||||
return false;
|
||||
fi->seek(exe_offset + ih.data_pages_offset, SEEK_SET);
|
||||
// FIXME: 1024 could be too large for some files
|
||||
return readPackHeader(1024) ? 1 : -1;
|
||||
//int len = 1024;
|
||||
int len = UPX_MIN(getImageSize(), 256u);
|
||||
return readPackHeader(len) ? 1 : -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -28,7 +28,6 @@
|
||||
|
||||
//#define WANT_STL
|
||||
#include "conf.h"
|
||||
#include "version.h"
|
||||
#include "file.h"
|
||||
#include "packer.h"
|
||||
#include "filter.h"
|
||||
@ -157,7 +156,7 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
|
||||
ph.saved_u_adler = ph.u_adler;
|
||||
ph.saved_c_adler = ph.c_adler;
|
||||
// update checksum of uncompressed data
|
||||
ph.u_adler = upx_adler32(ph.u_adler,in,ph.u_len);
|
||||
ph.u_adler = upx_adler32(in, ph.u_len, ph.u_adler);
|
||||
|
||||
// set compression paramters
|
||||
upx_compress_config_t conf;
|
||||
@ -231,7 +230,7 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
|
||||
return false;
|
||||
|
||||
// update checksum of compressed data
|
||||
ph.c_adler = upx_adler32(ph.c_adler,out,ph.c_len);
|
||||
ph.c_adler = upx_adler32(out, ph.c_len, ph.c_adler);
|
||||
// Decompress and verify. Skip this when using the fastest level.
|
||||
if (ph.level > 1)
|
||||
{
|
||||
@ -245,7 +244,7 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
|
||||
throwInternalError("decompression failed (size error)");
|
||||
|
||||
// verify decompression
|
||||
if (ph.u_adler != upx_adler32(ph.saved_u_adler,in,ph.u_len))
|
||||
if (ph.u_adler != upx_adler32(in, ph.u_len, ph.saved_u_adler))
|
||||
throwInternalError("decompression failed (checksum error)");
|
||||
}
|
||||
return true;
|
||||
@ -303,7 +302,7 @@ void Packer::decompress(const upx_bytep in, upx_bytep out,
|
||||
// verify checksum of compressed data
|
||||
if (verify_checksum)
|
||||
{
|
||||
adler = upx_adler32(ph.saved_c_adler, in, ph.c_len);
|
||||
adler = upx_adler32(in, ph.c_len, ph.saved_c_adler);
|
||||
if (adler != ph.c_adler)
|
||||
throwChecksumError();
|
||||
}
|
||||
@ -317,7 +316,7 @@ void Packer::decompress(const upx_bytep in, upx_bytep out,
|
||||
// verify checksum of decompressed data
|
||||
if (verify_checksum)
|
||||
{
|
||||
adler = upx_adler32(ph.saved_u_adler, out, ph.u_len);
|
||||
adler = upx_adler32(out, ph.u_len, ph.saved_u_adler);
|
||||
if (adler != ph.u_adler)
|
||||
throwChecksumError();
|
||||
}
|
||||
@ -927,18 +926,19 @@ char const *Packer::identstr(unsigned &size)
|
||||
static const char identbig[] =
|
||||
"\n\0"
|
||||
"$Info: "
|
||||
"This file is packed with the UPX executable packer http://upx.tsx.org $"
|
||||
"This file is packed with the UPX executable packer http://upx.sf.net $"
|
||||
"\n\0"
|
||||
"$Id: UPX "
|
||||
UPX_VERSION_STRING4
|
||||
" Copyright (C) 1996-2001 the UPX Team. All Rights Reserved. $"
|
||||
" Copyright (C) 1996-2002 the UPX Team. All Rights Reserved. $"
|
||||
"\n";
|
||||
|
||||
static const char identsmall[] =
|
||||
"\n"
|
||||
"$Id: UPX "
|
||||
"(C) 1996-2001 the UPX Team. All Rights Reserved. http://upx.tsx.org $"
|
||||
"(C) 1996-2002 the UPX Team. All Rights Reserved. http://upx.sf.net $"
|
||||
"\n";
|
||||
// static const char identtiny[] = UPX_VERSION_STRING4;
|
||||
// FIXME
|
||||
|
||||
if (opt->small) {
|
||||
size = sizeof(identsmall);
|
||||
|
||||
@ -112,7 +112,7 @@ public:
|
||||
virtual ~Packer();
|
||||
|
||||
virtual int getVersion() const = 0;
|
||||
// A unique integer ID for this executable format. See unupx.h.
|
||||
// A unique integer ID for this executable format. See conf.h.
|
||||
virtual int getFormat() const = 0;
|
||||
virtual const char *getName() const = 0;
|
||||
virtual const int *getCompressionMethods(int method, int level) const = 0;
|
||||
|
||||
@ -123,7 +123,7 @@ static __inline__
|
||||
unsigned short make_cell(screen_t *this, int ch, int attr)
|
||||
{
|
||||
UNUSED(this);
|
||||
return ((attr & 0xff) << 8) | (ch & 0xff);
|
||||
return (unsigned short) (((attr & 0xff) << 8) | (ch & 0xff));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -331,11 +331,11 @@ static int init(screen_t *this, int fd)
|
||||
int attr;
|
||||
unsigned short a;
|
||||
|
||||
sprintf(vc_name, "/dev/vcsa%d", (int) MINOR(st.st_rdev));
|
||||
upx_snprintf(vc_name, sizeof(vc_name), "/dev/vcsa%d", (int) MINOR(st.st_rdev));
|
||||
this->data->fd = open(vc_name, O_RDWR);
|
||||
if (this->data->fd == -1)
|
||||
{
|
||||
sprintf(vc_name, "/dev/vcc/a%d", (int) MINOR(st.st_rdev));
|
||||
upx_snprintf(vc_name, sizeof(vc_name), "/dev/vcc/a%d", (int) MINOR(st.st_rdev));
|
||||
this->data->fd = open(vc_name, O_RDWR);
|
||||
}
|
||||
if (this->data->fd != -1)
|
||||
|
||||
@ -188,6 +188,7 @@ static void putCharAttr(screen_t *this, int ch, int attr, int x, int y)
|
||||
{
|
||||
CHAR_INFO ci;
|
||||
SMALL_RECT region = { P(x), P(y), P(x), P(y) };
|
||||
ci.Char.UnicodeChar = 0;
|
||||
ci.Char.AsciiChar = (CHAR) ch;
|
||||
ci.Attributes = (WORD) attr;
|
||||
WriteConsoleOutputA(this->data->ho, &ci, size11, pos00, ®ion);
|
||||
@ -213,6 +214,7 @@ static void putStringAttr(screen_t *this, const char *s, int attr, int x, int y)
|
||||
SMALL_RECT region = { P(x), P(y), P(x + l - 1), P(y) };
|
||||
for (i = 0; i < l; i++)
|
||||
{
|
||||
ci[i].Char.UnicodeChar = 0;
|
||||
ci[i].Char.AsciiChar = *s++;
|
||||
ci[i].Attributes = (WORD) attr;
|
||||
}
|
||||
@ -355,6 +357,7 @@ static void updateLineN(screen_t *this, const void *line, int y, int len)
|
||||
SMALL_RECT region = { 0, P(y), P(0 + l - 1), P(y) };
|
||||
for (i = 0; i < l; i++)
|
||||
{
|
||||
ci[i].Char.UnicodeChar = 0;
|
||||
ci[i].Char.AsciiChar = *s++;
|
||||
ci[i].Attributes = *s++;
|
||||
}
|
||||
|
||||
997
src/snprintf.cpp
Normal file
997
src/snprintf.cpp
Normal file
@ -0,0 +1,997 @@
|
||||
/*
|
||||
* Copyright Patrick Powell 1995
|
||||
* This code is based on code written by Patrick Powell (papowell@astart.com)
|
||||
* It may be used for any purpose as long as this notice remains intact
|
||||
* on all source code distributions
|
||||
*/
|
||||
|
||||
/**************************************************************
|
||||
* Original:
|
||||
* Patrick Powell Tue Apr 11 09:48:21 PDT 1995
|
||||
* A bombproof version of doprnt (dopr) included.
|
||||
* Sigh. This sort of thing is always nasty do deal with. Note that
|
||||
* the version here does not include floating point...
|
||||
*
|
||||
* snprintf() is used instead of sprintf() as it does limit checks
|
||||
* for string length. This covers a nasty loophole.
|
||||
*
|
||||
* The other functions are there to prevent NULL pointers from
|
||||
* causing nast effects.
|
||||
*
|
||||
* More Recently:
|
||||
* Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
|
||||
* This was ugly. It is still ugly. I opted out of floating point
|
||||
* numbers, but the formatter understands just about everything
|
||||
* from the normal C string format, at least as far as I can tell from
|
||||
* the Solaris 2.5 printf(3S) man page.
|
||||
*
|
||||
* Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
|
||||
* Ok, added some minimal floating point support, which means this
|
||||
* probably requires libm on most operating systems. Don't yet
|
||||
* support the exponent (e,E) and sigfig (g,G). Also, fmtint()
|
||||
* was pretty badly broken, it just wasn't being exercised in ways
|
||||
* which showed it, so that's been fixed. Also, formated the code
|
||||
* to mutt conventions, and removed dead code left over from the
|
||||
* original. Also, there is now a builtin-test, just compile with:
|
||||
* gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
|
||||
* and run snprintf for results.
|
||||
*
|
||||
* Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
|
||||
* The PGP code was using unsigned hexadecimal formats.
|
||||
* Unfortunately, unsigned formats simply didn't work.
|
||||
*
|
||||
* Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
|
||||
* The original code assumed that both snprintf() and vsnprintf() were
|
||||
* missing. Some systems only have snprintf() but not vsnprintf(), so
|
||||
* the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
|
||||
*
|
||||
* Andrew Tridgell (tridge@samba.org) Oct 1998
|
||||
* fixed handling of %.0f
|
||||
* added test for HAVE_LONG_DOUBLE
|
||||
*
|
||||
* tridge@samba.org, idra@samba.org, April 2001
|
||||
* got rid of fcvt code (twas buggy and made testing harder)
|
||||
* added C99 semantics
|
||||
*
|
||||
* markus@oberhumer.com, August 2002
|
||||
* large modifications for use in UPX
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
|
||||
#if 1
|
||||
#include "conf.h"
|
||||
#else
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#undef LLONG
|
||||
#undef ULLONG
|
||||
#if 1 && defined(upx_int64l)
|
||||
# define LLONG upx_int64l
|
||||
# define ULLONG upx_uint64l
|
||||
#else
|
||||
# define LLONG long int
|
||||
# define ULLONG unsigned long int
|
||||
#endif
|
||||
|
||||
#undef NO_FLOAT
|
||||
#undef LDOUBLE
|
||||
#if 1
|
||||
# define NO_FLOAT
|
||||
# define float error_no_float
|
||||
# define double error_no_float
|
||||
#elif 0 || defined(HAVE_LONG_DOUBLE)
|
||||
# define LDOUBLE long double
|
||||
#else
|
||||
# define LDOUBLE double
|
||||
#endif
|
||||
|
||||
/*
|
||||
* dopr(): poor man's version of doprintf
|
||||
*/
|
||||
|
||||
/* format read states */
|
||||
#define DP_S_DEFAULT 0
|
||||
#define DP_S_FLAGS 1
|
||||
#define DP_S_MIN 2
|
||||
#define DP_S_DOT 3
|
||||
#define DP_S_MAX 4
|
||||
#define DP_S_MOD 5
|
||||
#define DP_S_CONV 6
|
||||
#define DP_S_DONE 7
|
||||
|
||||
/* format flags - Bits */
|
||||
#define DP_F_MINUS (1 << 0)
|
||||
#define DP_F_PLUS (1 << 1)
|
||||
#define DP_F_SPACE (1 << 2)
|
||||
#define DP_F_NUM (1 << 3)
|
||||
#define DP_F_ZERO (1 << 4)
|
||||
#define DP_F_UP (1 << 5)
|
||||
#define DP_F_UNSIGNED (1 << 6)
|
||||
|
||||
/* Conversion Flags */
|
||||
#define DP_C_SHORT 1
|
||||
#define DP_C_LONG 2
|
||||
#define DP_C_LDOUBLE 3
|
||||
#define DP_C_LLONG 4
|
||||
|
||||
#define char_to_int(p) ((p)- '0')
|
||||
#undef MAX
|
||||
#define MAX(p,q) (((p) >= (q)) ? (p) : (q))
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, int c)
|
||||
{
|
||||
if (*currlen < maxlen)
|
||||
buffer[*currlen] = (char) c;
|
||||
*currlen += 1;
|
||||
}
|
||||
|
||||
|
||||
static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
|
||||
const char *value, int flags, int min, int max)
|
||||
{
|
||||
int padlen, strln; /* amount to pad */
|
||||
int cnt = 0;
|
||||
|
||||
#ifdef DEBUG_SNPRINTF
|
||||
printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value);
|
||||
#endif
|
||||
if (value == NULL)
|
||||
value = "<NULL>";
|
||||
|
||||
for (strln = 0; value[strln]; ) /* strlen */
|
||||
++strln;
|
||||
padlen = min - strln;
|
||||
if (padlen < 0)
|
||||
padlen = 0;
|
||||
if (flags & DP_F_MINUS)
|
||||
padlen = -padlen; /* Left Justify */
|
||||
|
||||
while ((padlen > 0) && (cnt < max)) {
|
||||
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||
--padlen;
|
||||
++cnt;
|
||||
}
|
||||
while (*value && (cnt < max)) {
|
||||
dopr_outch (buffer, currlen, maxlen, *value++);
|
||||
++cnt;
|
||||
}
|
||||
while ((padlen < 0) && (cnt < max)) {
|
||||
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||
++padlen;
|
||||
++cnt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
|
||||
static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
|
||||
LLONG value, unsigned base, int min, int max, int flags)
|
||||
{
|
||||
int signvalue = 0;
|
||||
ULLONG uvalue;
|
||||
char convert[64+1];
|
||||
int place = 0;
|
||||
int spadlen = 0; /* amount to space pad */
|
||||
int zpadlen = 0; /* amount to zero pad */
|
||||
const char *digits;
|
||||
|
||||
if (min < 0)
|
||||
min = 0;
|
||||
if (max < 0)
|
||||
max = 0;
|
||||
|
||||
uvalue = value;
|
||||
if (!(flags & DP_F_UNSIGNED)) {
|
||||
if( value < 0 ) {
|
||||
signvalue = '-';
|
||||
uvalue = -value;
|
||||
} else {
|
||||
if (flags & DP_F_PLUS) /* Do a sign (+/i) */
|
||||
signvalue = '+';
|
||||
else if (flags & DP_F_SPACE)
|
||||
signvalue = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
digits = (flags & DP_F_UP) ? "0123456789ABCDEF" : "0123456789abcdef";
|
||||
do {
|
||||
convert[place] = digits[(unsigned) (uvalue % base)];
|
||||
uvalue /= base;
|
||||
} while (++place < (int)sizeof(convert) - 1 && uvalue);
|
||||
convert[place] = 0;
|
||||
|
||||
zpadlen = max - place;
|
||||
spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
|
||||
if (zpadlen < 0) zpadlen = 0;
|
||||
if (spadlen < 0) spadlen = 0;
|
||||
if (flags & DP_F_ZERO) {
|
||||
zpadlen = MAX(zpadlen, spadlen);
|
||||
spadlen = 0;
|
||||
}
|
||||
if (flags & DP_F_MINUS)
|
||||
spadlen = -spadlen; /* Left Justifty */
|
||||
|
||||
#ifdef DEBUG_SNPRINTF
|
||||
printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
|
||||
zpadlen, spadlen, min, max, place);
|
||||
#endif
|
||||
|
||||
/* Spaces */
|
||||
while (spadlen > 0) {
|
||||
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||
--spadlen;
|
||||
}
|
||||
|
||||
/* Sign */
|
||||
if (signvalue)
|
||||
dopr_outch (buffer, currlen, maxlen, signvalue);
|
||||
|
||||
/* Zeros */
|
||||
while (zpadlen > 0) {
|
||||
dopr_outch (buffer, currlen, maxlen, '0');
|
||||
--zpadlen;
|
||||
}
|
||||
|
||||
/* Digits */
|
||||
while (place > 0)
|
||||
dopr_outch (buffer, currlen, maxlen, convert[--place]);
|
||||
|
||||
/* Left Justified spaces */
|
||||
while (spadlen < 0) {
|
||||
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||
++spadlen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// floating format support
|
||||
**************************************************************************/
|
||||
|
||||
#if !defined(NO_FLOAT)
|
||||
|
||||
static LDOUBLE abs_val(LDOUBLE value)
|
||||
{
|
||||
LDOUBLE result = value;
|
||||
|
||||
if (value < 0)
|
||||
result = -value;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static LDOUBLE POW10(int exp)
|
||||
{
|
||||
LDOUBLE result = 1;
|
||||
|
||||
while (exp) {
|
||||
result *= 10;
|
||||
exp--;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static LLONG ROUND(LDOUBLE value)
|
||||
{
|
||||
LLONG intpart;
|
||||
|
||||
intpart = (LLONG)value;
|
||||
value = value - intpart;
|
||||
if (value >= 0.5) intpart++;
|
||||
|
||||
return intpart;
|
||||
}
|
||||
|
||||
/* a replacement for modf that doesn't need the math library. Should
|
||||
be portable, but slow */
|
||||
static double my_modf(double x0, double *iptr)
|
||||
{
|
||||
int i;
|
||||
long l;
|
||||
double x = x0;
|
||||
double f = 1.0;
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
l = (long)x;
|
||||
if (l <= (x+1) && l >= (x-1)) break;
|
||||
x *= 0.1;
|
||||
f *= 10.0;
|
||||
}
|
||||
|
||||
if (i == 100) {
|
||||
/* yikes! the number is beyond what we can handle. What do we do? */
|
||||
*iptr = 0.0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (i != 0) {
|
||||
double i2, ret;
|
||||
|
||||
ret = my_modf(x0-l*f, &i2);
|
||||
*iptr = l*f + i2;
|
||||
return ret;
|
||||
}
|
||||
|
||||
*iptr = l;
|
||||
return x - *iptr;
|
||||
}
|
||||
|
||||
|
||||
static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
|
||||
LDOUBLE fvalue, int min, int max, int flags)
|
||||
{
|
||||
/* avoid warnings with `gcc -Wshadow' */
|
||||
#undef index
|
||||
#define index iindex
|
||||
int signvalue = 0;
|
||||
double ufvalue;
|
||||
char iconvert[311+1];
|
||||
char fconvert[311+1];
|
||||
int iplace = 0;
|
||||
int fplace = 0;
|
||||
int padlen = 0; /* amount to pad */
|
||||
int zpadlen = 0;
|
||||
const char *digits;
|
||||
int index;
|
||||
double intpart;
|
||||
double fracpart;
|
||||
double temp;
|
||||
|
||||
/*
|
||||
* AIX manpage says the default is 0, but Solaris says the default
|
||||
* is 6, and sprintf on AIX defaults to 6
|
||||
*/
|
||||
if (min < 0)
|
||||
min = 0;
|
||||
if (max < 0)
|
||||
max = 6;
|
||||
|
||||
ufvalue = abs_val (fvalue);
|
||||
|
||||
if (fvalue < 0) {
|
||||
signvalue = '-';
|
||||
} else {
|
||||
if (flags & DP_F_PLUS) { /* Do a sign (+/i) */
|
||||
signvalue = '+';
|
||||
} else {
|
||||
if (flags & DP_F_SPACE)
|
||||
signvalue = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
digits = "0123456789ABCDEF";
|
||||
#if 0
|
||||
digits = (flags & DP_F_UP) ? "0123456789ABCDEF" : "0123456789abcdef";
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Sorry, we only support 16 digits past the decimal because of our
|
||||
* conversion method
|
||||
*/
|
||||
if (max > 16)
|
||||
max = 16;
|
||||
|
||||
/* We "cheat" by converting the fractional part to integer by
|
||||
* multiplying by a factor of 10
|
||||
*/
|
||||
|
||||
temp = ufvalue;
|
||||
my_modf(temp, &intpart);
|
||||
|
||||
fracpart = ROUND((POW10(max)) * (ufvalue - intpart));
|
||||
|
||||
if (fracpart >= POW10(max)) {
|
||||
intpart++;
|
||||
fracpart -= POW10(max);
|
||||
}
|
||||
|
||||
/* Convert integer part */
|
||||
do {
|
||||
temp = intpart;
|
||||
my_modf(intpart*0.1, &intpart);
|
||||
temp = temp*0.1;
|
||||
index = (int) ((temp - intpart + 0.05) * 10.0);
|
||||
/* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */
|
||||
/* printf ("%llf, %f, %x\n", temp, intpart, index); */
|
||||
iconvert[iplace] = digits[index];
|
||||
} while (++iplace < (int)sizeof(iconvert) - 1 && intpart);
|
||||
iconvert[iplace] = 0;
|
||||
|
||||
/* Convert fractional part */
|
||||
if (fracpart)
|
||||
{
|
||||
do {
|
||||
temp = fracpart;
|
||||
my_modf(fracpart*0.1, &fracpart);
|
||||
temp = temp*0.1;
|
||||
index = (int) ((temp - fracpart + 0.05) * 10.0);
|
||||
/* index = (int) ((((temp/10) -fracpart) +0.05) *10); */
|
||||
/* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */
|
||||
fconvert[fplace] = digits[index];
|
||||
} while (++fplace < (int)sizeof(fconvert) - 1 && fracpart);
|
||||
}
|
||||
fconvert[fplace] = 0;
|
||||
|
||||
/* -1 for decimal point, another -1 if we are printing a sign */
|
||||
padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
|
||||
zpadlen = max - fplace;
|
||||
if (zpadlen < 0) zpadlen = 0;
|
||||
if (padlen < 0)
|
||||
padlen = 0;
|
||||
if (flags & DP_F_MINUS)
|
||||
padlen = -padlen; /* Left Justifty */
|
||||
|
||||
if ((flags & DP_F_ZERO) && (padlen > 0)) {
|
||||
if (signvalue) {
|
||||
dopr_outch (buffer, currlen, maxlen, signvalue);
|
||||
--padlen;
|
||||
signvalue = 0;
|
||||
}
|
||||
while (padlen > 0) {
|
||||
dopr_outch (buffer, currlen, maxlen, '0');
|
||||
--padlen;
|
||||
}
|
||||
}
|
||||
while (padlen > 0) {
|
||||
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||
--padlen;
|
||||
}
|
||||
if (signvalue)
|
||||
dopr_outch (buffer, currlen, maxlen, signvalue);
|
||||
|
||||
while (iplace > 0)
|
||||
dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
|
||||
|
||||
#ifdef DEBUG_SNPRINTF
|
||||
printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Decimal point. This should probably use locale to find the correct
|
||||
* char to print out.
|
||||
*/
|
||||
if (max > 0) {
|
||||
dopr_outch (buffer, currlen, maxlen, '.');
|
||||
|
||||
while (fplace > 0)
|
||||
dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
|
||||
}
|
||||
|
||||
while (zpadlen > 0) {
|
||||
dopr_outch (buffer, currlen, maxlen, '0');
|
||||
--zpadlen;
|
||||
}
|
||||
|
||||
while (padlen < 0) {
|
||||
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||
++padlen;
|
||||
}
|
||||
#undef index
|
||||
}
|
||||
|
||||
|
||||
#endif /* !defined(NO_FLOAT) */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// dopr()
|
||||
**************************************************************************/
|
||||
|
||||
static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args)
|
||||
{
|
||||
char ch;
|
||||
LLONG value;
|
||||
#if !defined(NO_FLOAT)
|
||||
LDOUBLE fvalue;
|
||||
#endif
|
||||
const char *strvalue;
|
||||
int min;
|
||||
int max;
|
||||
int state;
|
||||
int flags;
|
||||
int cflags;
|
||||
size_t currlen;
|
||||
|
||||
state = DP_S_DEFAULT;
|
||||
currlen = flags = cflags = min = 0;
|
||||
max = -1;
|
||||
ch = *format++;
|
||||
|
||||
while (state != DP_S_DONE) {
|
||||
if (ch == '\0')
|
||||
state = DP_S_DONE;
|
||||
|
||||
switch(state) {
|
||||
case DP_S_DEFAULT:
|
||||
if (ch == '%')
|
||||
state = DP_S_FLAGS;
|
||||
else
|
||||
dopr_outch (buffer, &currlen, maxlen, ch);
|
||||
ch = *format++;
|
||||
break;
|
||||
case DP_S_FLAGS:
|
||||
switch (ch) {
|
||||
case '-':
|
||||
flags |= DP_F_MINUS;
|
||||
ch = *format++;
|
||||
break;
|
||||
case '+':
|
||||
flags |= DP_F_PLUS;
|
||||
ch = *format++;
|
||||
break;
|
||||
case ' ':
|
||||
flags |= DP_F_SPACE;
|
||||
ch = *format++;
|
||||
break;
|
||||
case '#':
|
||||
flags |= DP_F_NUM;
|
||||
ch = *format++;
|
||||
break;
|
||||
case '0':
|
||||
flags |= DP_F_ZERO;
|
||||
ch = *format++;
|
||||
break;
|
||||
default:
|
||||
state = DP_S_MIN;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DP_S_MIN:
|
||||
if (isdigit((unsigned char)ch)) {
|
||||
min = 10*min + char_to_int(ch);
|
||||
ch = *format++;
|
||||
} else if (ch == '*') {
|
||||
min = va_arg (args, int);
|
||||
ch = *format++;
|
||||
state = DP_S_DOT;
|
||||
} else {
|
||||
state = DP_S_DOT;
|
||||
}
|
||||
break;
|
||||
case DP_S_DOT:
|
||||
if (ch == '.') {
|
||||
state = DP_S_MAX;
|
||||
ch = *format++;
|
||||
} else {
|
||||
state = DP_S_MOD;
|
||||
}
|
||||
break;
|
||||
case DP_S_MAX:
|
||||
if (isdigit((unsigned char)ch)) {
|
||||
if (max < 0)
|
||||
max = 0;
|
||||
max = 10*max + char_to_int(ch);
|
||||
ch = *format++;
|
||||
} else if (ch == '*') {
|
||||
max = va_arg (args, int);
|
||||
ch = *format++;
|
||||
state = DP_S_MOD;
|
||||
} else {
|
||||
state = DP_S_MOD;
|
||||
}
|
||||
break;
|
||||
case DP_S_MOD:
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
cflags = DP_C_SHORT;
|
||||
ch = *format++;
|
||||
break;
|
||||
case 'l':
|
||||
cflags = DP_C_LONG;
|
||||
ch = *format++;
|
||||
if (ch == 'l') { /* It's a long long */
|
||||
cflags = DP_C_LLONG;
|
||||
ch = *format++;
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
cflags = DP_C_LDOUBLE;
|
||||
ch = *format++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
state = DP_S_CONV;
|
||||
break;
|
||||
case DP_S_CONV:
|
||||
switch (ch) {
|
||||
case 'd':
|
||||
case 'i':
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = va_arg (args, int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg (args, long int);
|
||||
else if (cflags == DP_C_LLONG)
|
||||
value = va_arg (args, LLONG);
|
||||
else
|
||||
value = va_arg (args, int);
|
||||
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
|
||||
break;
|
||||
case 'o':
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = va_arg (args, unsigned int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = (long)va_arg (args, unsigned long int);
|
||||
else if (cflags == DP_C_LLONG)
|
||||
value = (long)va_arg (args, ULLONG);
|
||||
else
|
||||
value = (long)va_arg (args, unsigned int);
|
||||
fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
|
||||
break;
|
||||
case 'u':
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = va_arg (args, unsigned int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = (long)va_arg (args, unsigned long int);
|
||||
else if (cflags == DP_C_LLONG)
|
||||
value = (LLONG)va_arg (args, ULLONG);
|
||||
else
|
||||
value = (long)va_arg (args, unsigned int);
|
||||
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
|
||||
break;
|
||||
case 'X':
|
||||
flags |= DP_F_UP;
|
||||
case 'x':
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = va_arg (args, unsigned int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = (long)va_arg (args, unsigned long int);
|
||||
else if (cflags == DP_C_LLONG)
|
||||
value = (LLONG)va_arg (args, ULLONG);
|
||||
else
|
||||
value = (long)va_arg (args, unsigned int);
|
||||
fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
|
||||
break;
|
||||
#if !defined(NO_FLOAT)
|
||||
case 'f':
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg (args, LDOUBLE);
|
||||
else
|
||||
fvalue = va_arg (args, double);
|
||||
/* um, floating point? */
|
||||
fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
|
||||
break;
|
||||
case 'E':
|
||||
flags |= DP_F_UP;
|
||||
case 'e':
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg (args, LDOUBLE);
|
||||
else
|
||||
fvalue = va_arg (args, double);
|
||||
break;
|
||||
case 'G':
|
||||
flags |= DP_F_UP;
|
||||
case 'g':
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg (args, LDOUBLE);
|
||||
else
|
||||
fvalue = va_arg (args, double);
|
||||
break;
|
||||
#else
|
||||
case 'f':
|
||||
case 'E':
|
||||
case 'e':
|
||||
case 'G':
|
||||
case 'g':
|
||||
assert(0);
|
||||
exit(255);
|
||||
#endif /* !defined(NO_FLOAT) */
|
||||
case 'c':
|
||||
dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
|
||||
break;
|
||||
case 's':
|
||||
strvalue = va_arg (args, char *);
|
||||
if (!strvalue) strvalue = "(NULL)";
|
||||
if (max == -1) {
|
||||
max = strlen(strvalue);
|
||||
}
|
||||
if (min > 0 && max >= 0 && min > max) max = min;
|
||||
fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
|
||||
break;
|
||||
case 'p':
|
||||
strvalue = (const char *) va_arg (args, void *);
|
||||
fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
|
||||
break;
|
||||
case 'n':
|
||||
if (cflags == DP_C_SHORT) {
|
||||
short int *num;
|
||||
num = va_arg (args, short int *);
|
||||
*num = (short int)currlen;
|
||||
} else if (cflags == DP_C_LONG) {
|
||||
long int *num;
|
||||
num = va_arg (args, long int *);
|
||||
*num = (long int)currlen;
|
||||
} else if (cflags == DP_C_LLONG) {
|
||||
LLONG *num;
|
||||
num = va_arg (args, LLONG *);
|
||||
*num = (LLONG)currlen;
|
||||
} else {
|
||||
int *num;
|
||||
num = va_arg (args, int *);
|
||||
*num = currlen;
|
||||
}
|
||||
break;
|
||||
case '%':
|
||||
dopr_outch (buffer, &currlen, maxlen, ch);
|
||||
break;
|
||||
case 'w':
|
||||
/* not supported yet, treat as next char */
|
||||
ch = *format++;
|
||||
break;
|
||||
default:
|
||||
/* Unknown, skip */
|
||||
break;
|
||||
}
|
||||
ch = *format++;
|
||||
state = DP_S_DEFAULT;
|
||||
flags = cflags = min = 0;
|
||||
max = -1;
|
||||
break;
|
||||
case DP_S_DONE:
|
||||
break;
|
||||
default:
|
||||
/* hmm? */
|
||||
break; /* some picky compilers need this */
|
||||
}
|
||||
}
|
||||
if (maxlen != 0) {
|
||||
if (currlen < maxlen - 1)
|
||||
buffer[currlen] = '\0';
|
||||
else
|
||||
buffer[maxlen - 1] = '\0';
|
||||
}
|
||||
|
||||
return currlen;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// public entries
|
||||
**************************************************************************/
|
||||
|
||||
// UPX version with assertions
|
||||
static int xdopr(char *buffer, size_t maxlen, const char *format, va_list args)
|
||||
{
|
||||
size_t ret;
|
||||
|
||||
// preconditions
|
||||
if (buffer != NULL)
|
||||
assert((int)maxlen > 0);
|
||||
else
|
||||
assert(maxlen == 0);
|
||||
|
||||
ret = dopr(buffer, maxlen, format, args);
|
||||
|
||||
// postconditions
|
||||
if (buffer != NULL)
|
||||
{
|
||||
assert((int)ret >= 0);
|
||||
assert(ret < maxlen);
|
||||
assert(buffer[ret] == '\0');
|
||||
}
|
||||
|
||||
return (int) ret;
|
||||
}
|
||||
|
||||
|
||||
int upx_vsnprintf(char *str, size_t count, const char *format, va_list ap)
|
||||
{
|
||||
return xdopr(str, count, format, ap);
|
||||
}
|
||||
|
||||
|
||||
int upx_snprintf(char *str, size_t count, const char *format,...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, format);
|
||||
ret = xdopr(str, count, format, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int upx_vasprintf(char **ptr, const char *format, va_list ap)
|
||||
{
|
||||
int ret;
|
||||
|
||||
assert(ptr != NULL);
|
||||
*ptr = NULL;
|
||||
ret = xdopr(NULL, 0, format, ap);
|
||||
if (ret > 0)
|
||||
{
|
||||
*ptr = (char *) malloc(ret + 1);
|
||||
assert(*ptr != NULL);
|
||||
if (*ptr == NULL)
|
||||
return -1;
|
||||
ret = xdopr(*ptr, ret+1, format, ap);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int upx_asprintf(char **ptr, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, format);
|
||||
ret = upx_vasprintf(ptr, format, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if 0 || defined(TEST_SNPRINTF)
|
||||
|
||||
#undef sprintf
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#undef snprintf
|
||||
#define snprintf upx_snprintf
|
||||
//int sprintf(char *str,const char *fmt,...);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char buf1[1024];
|
||||
char buf2[1024];
|
||||
const char *fp_fmt[] = {
|
||||
"%1.1f",
|
||||
"%-1.5f",
|
||||
"%1.5f",
|
||||
"%123.9f",
|
||||
"%10.5f",
|
||||
"% 10.5f",
|
||||
"%+22.9f",
|
||||
"%+4.9f",
|
||||
"%01.3f",
|
||||
"%4f",
|
||||
"%3.1f",
|
||||
"%3.2f",
|
||||
"%.0f",
|
||||
"%f",
|
||||
"-16.16f",
|
||||
NULL
|
||||
};
|
||||
const double fp_nums[] = {
|
||||
6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
|
||||
0.9996, 1.996, 4.136, 0
|
||||
};
|
||||
const char *int_fmt[] = {
|
||||
"%-1.5d",
|
||||
"%1.5d",
|
||||
"%123.9d",
|
||||
"%5.5d",
|
||||
"%10.5d",
|
||||
"% 10.5d",
|
||||
"%+22.33d",
|
||||
"%01.3d",
|
||||
"%4d",
|
||||
"%d",
|
||||
NULL
|
||||
};
|
||||
const long int_nums[] = { -1, 134, 91340, 341, 0203, 0 };
|
||||
const char *str_fmt[] = {
|
||||
"10.5s",
|
||||
"5.10s",
|
||||
"10.1s",
|
||||
"0.10s",
|
||||
"10.0s",
|
||||
"1.10s",
|
||||
"%s",
|
||||
"%.1s",
|
||||
"%.10s",
|
||||
"%10s",
|
||||
0
|
||||
};
|
||||
const char *str_vals[] = {"hello", "a", "", "a longer string", NULL};
|
||||
int x, y;
|
||||
int fail = 0;
|
||||
int num = 0;
|
||||
|
||||
printf ("Testing snprintf format codes against system sprintf...\n");
|
||||
|
||||
for (x = 0; fp_fmt[x] ; x++) {
|
||||
for (y = 0; fp_nums[y] != 0 ; y++) {
|
||||
int l1 = snprintf(NULL, 0, fp_fmt[x], fp_nums[y]);
|
||||
int l2 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]);
|
||||
sprintf (buf2, fp_fmt[x], fp_nums[y]);
|
||||
if (strcmp (buf1, buf2)) {
|
||||
printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n",
|
||||
fp_fmt[x], buf1, buf2);
|
||||
fail++;
|
||||
}
|
||||
if (l1 != l2) {
|
||||
printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, fp_fmt[x]);
|
||||
fail++;
|
||||
}
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; int_fmt[x] ; x++) {
|
||||
for (y = 0; int_nums[y] != 0 ; y++) {
|
||||
int l1 = snprintf(0, 0, int_fmt[x], int_nums[y]);
|
||||
int l2 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]);
|
||||
sprintf (buf2, int_fmt[x], int_nums[y]);
|
||||
if (strcmp (buf1, buf2)) {
|
||||
printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n",
|
||||
int_fmt[x], buf1, buf2);
|
||||
fail++;
|
||||
}
|
||||
if (l1 != l2) {
|
||||
printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, int_fmt[x]);
|
||||
fail++;
|
||||
}
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; str_fmt[x] ; x++) {
|
||||
for (y = 0; str_vals[y] != 0 ; y++) {
|
||||
int l1 = snprintf(NULL, 0, str_fmt[x], str_vals[y]);
|
||||
int l2 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]);
|
||||
sprintf (buf2, str_fmt[x], str_vals[y]);
|
||||
if (strcmp (buf1, buf2)) {
|
||||
printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n",
|
||||
str_fmt[x], buf1, buf2);
|
||||
fail++;
|
||||
}
|
||||
if (l1 != l2) {
|
||||
printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, str_fmt[x]);
|
||||
fail++;
|
||||
}
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
printf ("%d tests failed out of %d.\n", fail, num);
|
||||
|
||||
printf("seeing how many digits we support\n");
|
||||
{
|
||||
double v0 = 0.12345678901234567890123456789012345678901;
|
||||
for (x=0; x<100; x++) {
|
||||
snprintf(buf1, sizeof(buf1), "%1.1f", v0*pow(10, x));
|
||||
sprintf(buf2, "%1.1f", v0*pow(10, x));
|
||||
if (strcmp(buf1, buf2) != 0) {
|
||||
printf("we seem to support %d digits\n", x-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* SNPRINTF_TEST */
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
62
src/snprintf.h
Normal file
62
src/snprintf.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* snprintf.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_SNPRINTF_H
|
||||
#define __UPX_SNPRINTF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_vsnprintf(char *str, size_t count, const char *format, va_list ap);
|
||||
int upx_snprintf(char *str, size_t count, const char *format,...);
|
||||
int upx_vasprintf(char **ptr, const char *format, va_list ap);
|
||||
int upx_asprintf(char **ptr, const char *format, ...);
|
||||
|
||||
#if 1
|
||||
# undef sprintf
|
||||
# define sprintf error_sprintf_is_dangerous_use_snprintf
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
# UPX stub Makefile (GNU make)
|
||||
#
|
||||
# see http://upx.sourceforge.net/download/tools/
|
||||
# for required support tools
|
||||
# for required build tools
|
||||
#
|
||||
|
||||
ifeq ($(strip $(UCLDIR)),)
|
||||
@ -76,13 +76,13 @@ NASM = /usr/topics/asm/nasm-20000903/nasm -O2 -w+macro-params -w+orphan-labe
|
||||
NASM = nasm -w+macro-params -w+orphan-labels
|
||||
NASM += -i$(srcdir)/
|
||||
|
||||
APP = perl -w $(srcdir)/scripts/app.pl
|
||||
APP_I386 = perl -w $(srcdir)/scripts/app_i386.pl
|
||||
BIN2H = perl -w $(srcdir)/scripts/bin2h.pl
|
||||
BRANDELF = perl -w $(srcdir)/scripts/brandelf.pl
|
||||
O2BIN = perl -w $(srcdir)/scripts/o2bin.pl
|
||||
##SETFOLD = /bin/sh $(srcdir)/scripts/setfold.sh
|
||||
##STRIPELF = perl -w $(srcdir)/scripts/stripelf.pl
|
||||
STRIPELF = ./util/sstrip/sstrip
|
||||
STRIPELF = $(srcdir)/util/sstrip/sstrip
|
||||
|
||||
# Use gcc 2.95.2 for smallest code.
|
||||
CC_LINUX_CFLAGS = -Wall -W -Wcast-align -Wcast-qual -Wwrite-strings
|
||||
@ -98,18 +98,18 @@ ifeq (1,1)
|
||||
# Preprocessor for the a68k 68000-assembler.
|
||||
CPP_M68K = gcc -I$(UCL_UPX) -E -x assembler-with-cpp -Wall -Wp,-P,-C,-traditional -D__A68K__
|
||||
##CPP_M68K = cpp -I$(UCL_UPX) -x assembler-with-cpp -P -C -traditional -nostdinc -D__A68K__
|
||||
APP_M68K = perl -w $(srcdir)/scripts/app_68k.pl
|
||||
APP_M68K = perl -w $(srcdir)/scripts/app_m68k.pl
|
||||
ASM_M68K = a68k -q -x
|
||||
else
|
||||
# Preprocessor for the asl 68000-assembler.
|
||||
CPP_M68K = gcc -I$(UCL_UPX) -E -x assembler-with-cpp -Wall -Wp,-P,-C,-traditional -D__ASL__
|
||||
APP_M68K = perl -w $(srcdir)/scripts/app_68k.pl
|
||||
ASM_M68K = sh $(srcdir)/scripts/asl_68k.sh
|
||||
APP_M68K = perl -w $(srcdir)/scripts/app_m68k.pl
|
||||
ASM_M68K = sh $(srcdir)/scripts/asl_m68k.sh
|
||||
endif
|
||||
|
||||
# MIPS R3000
|
||||
APP_R3K = perl -w $(srcdir)/scripts/app_r3k.pl
|
||||
ASM_R3K = asm5900 --nologo -q
|
||||
APP_MR3K = perl -w $(srcdir)/scripts/app_mr3k.pl
|
||||
ASM_MR3K = asm5900 --nologo -q
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
@ -119,7 +119,7 @@ ASM_R3K = asm5900 --nologo -q
|
||||
.PHONY: default all stubs mostlyclean clean distclean maintainer-clean ident strings
|
||||
|
||||
default:
|
||||
@echo "UPX info: type 'make all' if you have all the needed build tools."
|
||||
@echo "UPX info: type 'make all' if you have all the required build tools."
|
||||
|
||||
all: stubs ## upxb upxd
|
||||
|
||||
@ -150,10 +150,10 @@ strings: all
|
||||
# ************************************************************************/
|
||||
|
||||
.asm.asx:
|
||||
$(APP) $< $@
|
||||
$(APP_I386) $< $@
|
||||
|
||||
.ash.asy:
|
||||
$(APP) $< $@
|
||||
$(APP_I386) $< $@
|
||||
|
||||
|
||||
stubify.h: stub.asm
|
||||
@ -296,7 +296,7 @@ fold_elf86.o: fold_elf86.asm
|
||||
fold_elf86.h: l_lx_elf.o fold_elf86.o l_lx_elf86.lds
|
||||
ld -T $(srcdir)/l_lx_elf86.lds -Map $T.map -o $T.bin $T.o l_lx_elf.o
|
||||
objcopy -S -R .comment -R .note $T.bin
|
||||
./util/sstrip/sstrip $T.bin
|
||||
$(STRIPELF) $T.bin
|
||||
$(BRANDELF) $T.bin
|
||||
$(BIN2H) $T.bin linux_i386elf_fold $@
|
||||
|
||||
@ -309,7 +309,7 @@ fold_exec86.o: fold_exec86.asm
|
||||
fold_exec86.h: l_lx_exec.o fold_exec86.o l_lx_exec86.lds
|
||||
ld -T $(srcdir)/l_lx_exec86.lds -Map $T.map -o $T.bin $T.o l_lx_exec.o
|
||||
objcopy -S -R .comment -R .note $T.bin
|
||||
./util/sstrip/sstrip $T.bin
|
||||
$(STRIPELF) $T.bin
|
||||
$(BRANDELF) $T.bin
|
||||
$(BIN2H) $T.bin linux_i386exec_fold $@
|
||||
|
||||
@ -322,7 +322,7 @@ fold_sh86.o: fold_sh86.asm
|
||||
fold_sh86.h: l_lx_sh.o fold_sh86.o l_lx_sh86.lds
|
||||
ld -T $(srcdir)/l_lx_sh86.lds -Map $T.map -o $T.bin $T.o l_lx_sh.o
|
||||
objcopy -S -R .comment -R .note $T.bin
|
||||
./util/sstrip/sstrip $T.bin
|
||||
$(STRIPELF) $T.bin
|
||||
$(BRANDELF) $T.bin
|
||||
$(BIN2H) $T.bin linux_i386sh_fold $@
|
||||
|
||||
@ -349,8 +349,8 @@ upxd: l_lx_sep.o l_lx_sep86.asm
|
||||
# ************************************************************************/
|
||||
|
||||
l_psx.h: l_psx.asm
|
||||
$(APP_R3K) $< $T.asx
|
||||
$(ASM_R3K) $T.asx -I$(UCL_UPX) -o$T.bin -l$T.lst
|
||||
$(APP_MR3K) $< $T.asx
|
||||
$(ASM_MR3K) $T.asx -I$(UCL_UPX) -o$T.bin -l$T.lst
|
||||
$(BIN2H) $T.bin nrv_loader $@
|
||||
|
||||
|
||||
@ -364,19 +364,19 @@ DEPS2 = header.asy macros.asy
|
||||
$(STUBS): $(srcdir)/scripts/bin2h.pl
|
||||
|
||||
l_com.h: n2b_d16.asy $(DEPS2)
|
||||
l_djgpp2.h: n2b_d32.asy n2d_d32.asy $(DEPS2)
|
||||
l_exe.h: n2b_d8e.asy n2d_d8e.asy $(DEPS2)
|
||||
l_djgpp2.h: n2b_d32.asy n2d_d32.asy n2e_d32.asy $(DEPS2)
|
||||
l_exe.h: n2b_d8e.asy n2d_d8e.asy n2e_d8e.asy $(DEPS2)
|
||||
l_sys.h: n2b_d16.asy $(DEPS2)
|
||||
l_t_n2b.h: n2b_d.ash bits.ash $(DEPS1)
|
||||
l_t_n2bs.h: n2b_d.ash bits.ash $(DEPS1)
|
||||
l_t_n2d.h: n2d_d.ash bits.ash $(DEPS1)
|
||||
l_t_n2ds.h: n2d_d.ash bits.ash $(DEPS1)
|
||||
l_tmt.h: n2b_d32.asy n2d_d32.asy $(DEPS2)
|
||||
l_ext2.h: n2b_d32.asy n2d_d32.asy $(DEPS2)
|
||||
l_vmlinz.h: n2b_d32.asy n2d_d32.asy $(DEPS2)
|
||||
l_vxd.h: n2b_d32.asy n2d_d32.asy $(DEPS2)
|
||||
l_wcle.h: n2b_d32.asy n2d_d32.asy $(DEPS2)
|
||||
l_w32pe.h: n2b_d32.asy n2d_d32.asy $(DEPS2)
|
||||
l_t_n2b.h: n2b_d.ash bits.ash $(DEPS1)
|
||||
l_t_n2bs.h: n2b_d.ash bits.ash $(DEPS1)
|
||||
l_t_n2d.h: n2d_d.ash bits.ash $(DEPS1)
|
||||
l_t_n2ds.h: n2d_d.ash bits.ash $(DEPS1)
|
||||
l_t_n2e.h: n2e_d.ash bits.ash $(DEPS1)
|
||||
l_t_n2es.h: n2e_d.ash bits.ash $(DEPS1)
|
||||
l_tmt.h: n2b_d32.asy n2d_d32.asy n2e_d32.asy $(DEPS2)
|
||||
l_vxd.h: n2b_d32.asy n2d_d32.asy n2e_d32.asy $(DEPS2)
|
||||
l_wcle.h: n2b_d32.asy n2d_d32.asy n2e_d32.asy $(DEPS2)
|
||||
l_w32pe.h: n2b_d32.asy n2d_d32.asy n2e_d32.asy $(DEPS2)
|
||||
|
||||
l_lx_elf86.h: l_lx_elf86.asm macros.ash macros.asy
|
||||
l_lx_exec86.h: l_lx_exec86.asm macros.ash macros.asy
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
;
|
||||
; This file is part of the UPX executable compressor.
|
||||
;
|
||||
; Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer
|
||||
; Copyright (C) 1996-2001 Laszlo Molnar
|
||||
; Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
; Copyright (C) 1996-2002 Laszlo Molnar
|
||||
; All Rights Reserved.
|
||||
;
|
||||
; UPX and the UCL library are free software; you can redistribute them
|
||||
@ -21,8 +21,8 @@
|
||||
; If not, write to the Free Software Foundation, Inc.,
|
||||
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
;
|
||||
; Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
; markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
; Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
; <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
;
|
||||
|
||||
|
||||
@ -85,6 +85,7 @@ do_copy:
|
||||
|
||||
%include "n2b_d8e.ash"
|
||||
%include "n2d_d8e.ash"
|
||||
%include "n2e_d8e.ash"
|
||||
|
||||
; =============
|
||||
; ============= RELOCATION
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#! /usr/bin/perl -w
|
||||
#
|
||||
# app.pl -- assembly preprocessor for upx
|
||||
# app_i386.pl -- assembly preprocessor for upx
|
||||
#
|
||||
# This file is part of the UPX executable compressor.
|
||||
#
|
||||
@ -1,6 +1,6 @@
|
||||
#! /usr/bin/perl -w
|
||||
#
|
||||
# app_68k.pl -- assembly preprocessor for upx
|
||||
# app_m68k.pl -- assembly preprocessor for upx
|
||||
#
|
||||
# This file is part of the UPX executable compressor.
|
||||
#
|
||||
@ -28,7 +28,7 @@
|
||||
#
|
||||
|
||||
#
|
||||
# usage: app_68k.pl infile outfile
|
||||
# usage: app_m68k.pl infile outfile
|
||||
#
|
||||
|
||||
$in = shift || die;
|
||||
@ -1,6 +1,6 @@
|
||||
#! /usr/bin/perl -w
|
||||
#
|
||||
# app_r3k.pl -- assembly preprocessor for upx
|
||||
# app_mr3k.pl -- assembly preprocessor for upx
|
||||
#
|
||||
# This file is part of the UPX executable compressor.
|
||||
#
|
||||
@ -28,7 +28,7 @@
|
||||
#
|
||||
|
||||
#
|
||||
# usage: app_r3k.pl infile outfile
|
||||
# usage: app_mr3k.pl infile outfile
|
||||
#
|
||||
|
||||
$in = shift || die;
|
||||
50
src/stub/scripts/asl_m68k.sh
Normal file
50
src/stub/scripts/asl_m68k.sh
Normal file
@ -0,0 +1,50 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# asl_m68k.sh --
|
||||
#
|
||||
# This file is part of the UPX executable compressor.
|
||||
#
|
||||
# Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
# Copyright (C) 1996-2002 Laszlo Molnar
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# UPX and the UCL library are free software; you can redistribute them
|
||||
# and/or modify them under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; see the file COPYING.
|
||||
# If not, write to the Free Software Foundation, Inc.,
|
||||
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
# <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# wrapper for the ASL cross-assembler (version 1.42bld9)
|
||||
# http://john.ccac.rwth-aachen.de:8000/as/
|
||||
# http://john.ccac.rwth-aachen.de:8000/ftp/as/source/c_version/
|
||||
|
||||
file="$1"
|
||||
test -f "$file" || exit 1
|
||||
|
||||
ofile=`echo "$file" | sed 's/\.[a-z]*$/.o/'`
|
||||
|
||||
# convert ' to " in dc.x statements
|
||||
perl -p -i -e '
|
||||
s,\x27,",g if m,^\s*dc\.,;
|
||||
' "$file"
|
||||
|
||||
echo asl -q -xC -U -cpu 68000 -o "$ofile" -L "$file"
|
||||
asl -q -xC -U -cpu 68000 -o "$ofile" -L "$file"
|
||||
|
||||
exit 0
|
||||
|
||||
@ -53,7 +53,7 @@ if (1 && $st[7] <= 0) {
|
||||
}
|
||||
if (1 && $st[7] > 64*1024) {
|
||||
print STDERR "$ifile: ERROR: file is too big (${st[7]} bytes)\n";
|
||||
if ($st[7] > 1024*1024) {
|
||||
if ($ifile =~ /^fold/) {
|
||||
print STDERR " (please upgrade your binutils to 2.12.90.0.15 or better)\n";
|
||||
}
|
||||
exit(1);
|
||||
|
||||
22
src/ui.cpp
22
src/ui.cpp
@ -271,13 +271,15 @@ void UiPacker::startCallback(unsigned u_len, unsigned step,
|
||||
// set pass
|
||||
if (total_passes > 1)
|
||||
{
|
||||
int buflen, l;
|
||||
do {
|
||||
s->pass_digits++;
|
||||
total_passes /= 10;
|
||||
} while (total_passes > 0);
|
||||
int l = sprintf(&s->msg_buf[s->bar_pos], "%*d/%*d ",
|
||||
s->pass_digits, s->pass,
|
||||
s->pass_digits, s->total_passes);
|
||||
buflen = sizeof(s->msg_buf) - s->bar_pos;
|
||||
l = upx_snprintf(&s->msg_buf[s->bar_pos], buflen, "%*d/%*d ",
|
||||
s->pass_digits, s->pass,
|
||||
s->pass_digits, s->total_passes);
|
||||
if (l > 0 && s->bar_len - l > 10)
|
||||
{
|
||||
s->bar_len -= l;
|
||||
@ -385,7 +387,7 @@ void __UPX_ENTRY UiPacker::callback(upx_uint isize, upx_uint osize, int state, v
|
||||
if (state != -1 && state != 3) return;
|
||||
if (user)
|
||||
{
|
||||
UiPacker *uip = reinterpret_cast<UiPacker *>(user);
|
||||
UiPacker *uip = (UiPacker *) user;
|
||||
uip->doCallback(isize, osize);
|
||||
}
|
||||
}
|
||||
@ -440,9 +442,10 @@ void UiPacker::doCallback(unsigned isize, unsigned osize)
|
||||
if (osize > 0)
|
||||
ratio = get_ratio(isize, osize);
|
||||
|
||||
sprintf(m," %3d.%1d%% %c ",
|
||||
ratio / 10000, (ratio % 10000) / 1000,
|
||||
spinner[s->spin_counter & 3]);
|
||||
int buflen = &s->msg_buf[sizeof(s->msg_buf)] - m;
|
||||
upx_snprintf(m, buflen, " %3d.%1d%% %c ",
|
||||
ratio / 10000, (ratio % 10000) / 1000,
|
||||
spinner[s->spin_counter & 3]);
|
||||
assert((int)strlen(s->msg_buf) < 1 + 80);
|
||||
|
||||
s->pos = pos;
|
||||
@ -593,8 +596,9 @@ void UiPacker::uiListTotal(bool decompress)
|
||||
if (opt->verbose >= 1 && total_files >= 2)
|
||||
{
|
||||
char name[32];
|
||||
upx_snprintf(name,sizeof(name),"[ %ld file%s ]", total_files_done, total_files_done == 1 ? "" : "s");
|
||||
con_fprintf(stdout,"%s%s\n",
|
||||
upx_snprintf(name, sizeof(name), "[ %ld file%s ]",
|
||||
total_files_done, total_files_done == 1 ? "" : "s");
|
||||
con_fprintf(stdout, "%s%s\n",
|
||||
header_line2,
|
||||
mkline(total_fu_len, total_fc_len,
|
||||
total_u_len, total_c_len,
|
||||
|
||||
13
src/upx.rc
13
src/upx.rc
@ -1,11 +1,18 @@
|
||||
#include <winres.h>
|
||||
#include "version.h"
|
||||
|
||||
#define VERSION_MAJOR ((UPX_VERSION_HEX >> 16) & 0xff)
|
||||
#define VERSION_MINOR ((UPX_VERSION_HEX >> 8) & 0xff)
|
||||
#define VERSION_MICRO ((UPX_VERSION_HEX >> 0) & 0xff)
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 90
|
||||
#define VERSION_MICRO 0
|
||||
#define VERSION_STRING UPX_VERSION_STRING
|
||||
|
||||
#define H(v,s) ((0x ## v) << (s))
|
||||
#define VERSION_HEX \
|
||||
(H(VERSION_MAJOR, 16) | H(VERSION_MINOR, 8) | H(VERSION_MICRO, 0))
|
||||
#if (VERSION_HEX != UPX_VERSION_HEX)
|
||||
# error "version mismatch"
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
|
||||
146
src/util.cpp
146
src/util.cpp
@ -63,6 +63,35 @@ int le32_compare(const void *e1, const void *e2)
|
||||
}
|
||||
|
||||
|
||||
int be16_compare_signed(const void *e1, const void *e2)
|
||||
{
|
||||
const int d1 = get_be16_signed(e1);
|
||||
const int d2 = get_be16_signed(e2);
|
||||
return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0);
|
||||
}
|
||||
|
||||
int be32_compare_signed(const void *e1, const void *e2)
|
||||
{
|
||||
const int d1 = get_be32_signed(e1);
|
||||
const int d2 = get_be32_signed(e2);
|
||||
return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0);
|
||||
}
|
||||
|
||||
int le16_compare_signed(const void *e1, const void *e2)
|
||||
{
|
||||
const int d1 = get_le16_signed(e1);
|
||||
const int d2 = get_le16_signed(e2);
|
||||
return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0);
|
||||
}
|
||||
|
||||
int le32_compare_signed(const void *e1, const void *e2)
|
||||
{
|
||||
const int d1 = get_le32_signed(e1);
|
||||
const int d2 = get_le32_signed(e2);
|
||||
return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// find util
|
||||
**************************************************************************/
|
||||
@ -144,74 +173,37 @@ upx_bytep pfind(const void *b, int blen, const void *what, int wlen)
|
||||
upx_bytep pfind_be16(const void *b, int blen, unsigned what)
|
||||
{
|
||||
unsigned char w[2];
|
||||
set_be16(w,what);
|
||||
return pfind(b,blen,w,2);
|
||||
set_be16(w, what);
|
||||
return pfind(b, blen, w, 2);
|
||||
}
|
||||
|
||||
|
||||
upx_bytep pfind_be32(const void *b, int blen, unsigned what)
|
||||
{
|
||||
unsigned char w[4];
|
||||
set_be32(w,what);
|
||||
return pfind(b,blen,w,4);
|
||||
set_be32(w, what);
|
||||
return pfind(b, blen, w, 4);
|
||||
}
|
||||
|
||||
|
||||
upx_bytep pfind_le16(const void *b, int blen, unsigned what)
|
||||
{
|
||||
unsigned char w[2];
|
||||
set_le16(w,what);
|
||||
return pfind(b,blen,w,2);
|
||||
set_le16(w, what);
|
||||
return pfind(b, blen, w, 2);
|
||||
}
|
||||
|
||||
|
||||
upx_bytep pfind_le32(const void *b, int blen, unsigned what)
|
||||
{
|
||||
unsigned char w[4];
|
||||
set_le32(w,what);
|
||||
return pfind(b,blen,w,4);
|
||||
set_le32(w, what);
|
||||
return pfind(b, blen, w, 4);
|
||||
}
|
||||
|
||||
#endif /* UPX_VERSION_HEX */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// string util
|
||||
**************************************************************************/
|
||||
|
||||
int upx_snprintf(char *str, long n, const char *format, ...)
|
||||
{
|
||||
int r = -1;
|
||||
if (n > 0)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args,format);
|
||||
r = upx_vsnprintf(str,n,format,args);
|
||||
va_end(args);
|
||||
}
|
||||
assert(r >= 0 && r < n); // UPX assertion
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int upx_vsnprintf(char *str, long n, const char *format, va_list ap)
|
||||
{
|
||||
int r = -1;
|
||||
if (n > 0)
|
||||
{
|
||||
#if defined(HAVE_VSNPRINTF)
|
||||
r = vsnprintf(str,(size_t)n,format,ap);
|
||||
#else
|
||||
r = vsprintf(str,format,ap);
|
||||
#endif
|
||||
// UPX extension: make sure the string is '\0' terminated in any case
|
||||
str[n-1] = 0;
|
||||
}
|
||||
assert(r >= 0 && r < n); // UPX assertion
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// ctype util
|
||||
**************************************************************************/
|
||||
@ -345,20 +337,21 @@ bool fn_is_same_file(const char *n1, const char *n2)
|
||||
#if 0 // not used
|
||||
|
||||
#if defined(HAVE_LOCALTIME)
|
||||
void tm2str(char *s, const struct tm *tmp)
|
||||
void tm2str(char *s, size_t size, const struct tm *tmp)
|
||||
{
|
||||
sprintf(s,"%04d-%02d-%02d %02d:%02d:%02d",
|
||||
(int) tmp->tm_year + 1900, (int) tmp->tm_mon + 1,
|
||||
(int) tmp->tm_mday,
|
||||
(int) tmp->tm_hour, (int) tmp->tm_min, (int) tmp->tm_sec);
|
||||
upx_snprintf(s, size, "%04d-%02d-%02d %02d:%02d:%02d",
|
||||
(int) tmp->tm_year + 1900, (int) tmp->tm_mon + 1,
|
||||
(int) tmp->tm_mday,
|
||||
(int) tmp->tm_hour, (int) tmp->tm_min, (int) tmp->tm_sec);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void time2str(char *s, const time_t *t)
|
||||
void time2str(char *s, size_t size, const time_t *t)
|
||||
{
|
||||
assert(size >= 18);
|
||||
#if defined(HAVE_LOCALTIME)
|
||||
tm2str(s,localtime(t));
|
||||
tm2str(s, size, localtime(t));
|
||||
#elif defined(HAVE_CTIME)
|
||||
const char *p = ctime(t);
|
||||
memset(s, ' ', 16);
|
||||
@ -402,12 +395,13 @@ bool set_method_name(char *buf, size_t size, int method, int level)
|
||||
|
||||
void center_string(char *buf, size_t size, const char *s)
|
||||
{
|
||||
size_t l = strlen(s);
|
||||
size_t len = size - 1;
|
||||
assert(l < size);
|
||||
memset(buf, ' ', len);
|
||||
memcpy(buf+(len-l)/2, s, l);
|
||||
buf[len] = 0;
|
||||
size_t l1 = size - 1;
|
||||
size_t l2 = strlen(s);
|
||||
assert(size > 0);
|
||||
assert(l2 < size);
|
||||
memset(buf, ' ', l1);
|
||||
memcpy(buf+(l1-l2)/2, s, l2);
|
||||
buf[l1] = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -442,12 +436,15 @@ bool file_exists(const char *name)
|
||||
}
|
||||
|
||||
|
||||
bool maketempname(char *ofilename, const char *ifilename,
|
||||
const char *ext, bool force)
|
||||
bool maketempname(char *ofilename, size_t size,
|
||||
const char *ifilename, const char *ext, bool force)
|
||||
{
|
||||
char *ofext = NULL, *ofname;
|
||||
int ofile = -1;
|
||||
|
||||
if (size <= 0)
|
||||
return false;
|
||||
|
||||
strcpy(ofilename, ifilename);
|
||||
for (ofname = fn_basename(ofilename); *ofname; ofname++)
|
||||
{
|
||||
@ -460,11 +457,12 @@ bool maketempname(char *ofilename, const char *ifilename,
|
||||
|
||||
while (ofile < 1000)
|
||||
{
|
||||
assert(strlen(ofilename) < size);
|
||||
if (!file_exists(ofilename))
|
||||
return true;
|
||||
if (!force)
|
||||
break;
|
||||
sprintf(ofext, ".%03d", ++ofile);
|
||||
upx_snprintf(ofext, 5, ".%03d", ++ofile);
|
||||
}
|
||||
|
||||
ofilename[0] = 0;
|
||||
@ -472,11 +470,15 @@ bool maketempname(char *ofilename, const char *ifilename,
|
||||
}
|
||||
|
||||
|
||||
bool makebakname(char *ofilename, const char *ifilename, bool force)
|
||||
bool makebakname(char *ofilename, size_t size,
|
||||
const char *ifilename, bool force)
|
||||
{
|
||||
char *ofext = NULL, *ofname;
|
||||
int ofile = -1;
|
||||
|
||||
if (size <= 0)
|
||||
return false;
|
||||
|
||||
strcpy(ofilename, ifilename);
|
||||
for (ofname = fn_basename(ofilename); *ofname; ofname++)
|
||||
{
|
||||
@ -495,11 +497,12 @@ bool makebakname(char *ofilename, const char *ifilename, bool force)
|
||||
|
||||
while (ofile < 1000)
|
||||
{
|
||||
assert(strlen(ofilename) < size);
|
||||
if (!file_exists(ofilename))
|
||||
return true;
|
||||
if (!force)
|
||||
break;
|
||||
sprintf(ofext, ".%03d", ++ofile);
|
||||
upx_snprintf(ofext, 5, ".%03d", ++ofile);
|
||||
}
|
||||
|
||||
ofilename[0] = 0;
|
||||
@ -532,21 +535,10 @@ bool isafile(int fd)
|
||||
|
||||
unsigned get_ratio(unsigned u_len, unsigned c_len)
|
||||
{
|
||||
#if (ULONG_MAX <= 0xffffffffL)
|
||||
# if defined(__GNUC__) || defined(__DMC__)
|
||||
const unsigned long long n = 1000000;
|
||||
# elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__WATCOMC__)
|
||||
const unsigned __int64 n = 1000000;
|
||||
# else
|
||||
# error "need a 64-bit integer type"
|
||||
# endif
|
||||
#else
|
||||
const unsigned long n = 1000000;
|
||||
#endif
|
||||
COMPILE_TIME_ASSERT(sizeof(n) >= 8);
|
||||
const unsigned n = 1000000;
|
||||
if (u_len <= 0)
|
||||
return (unsigned) n;
|
||||
return (unsigned) ((c_len * n) / u_len) + 5;
|
||||
return n;
|
||||
return (unsigned) ((c_len * (upx_uint64l)n) / u_len) + 5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
10
src/util.h
10
src/util.h
@ -34,18 +34,16 @@
|
||||
// misc. support functions
|
||||
**************************************************************************/
|
||||
|
||||
int upx_snprintf(char *str, long n, const char *format, ...);
|
||||
int upx_vsnprintf(char *str, long n, const char *format, va_list ap);
|
||||
|
||||
char *fn_basename(const char *name);
|
||||
int fn_strcmp(const char *n1, const char *n2);
|
||||
char *fn_strlwr(char *n);
|
||||
bool fn_has_ext(const char *name, const char *ext, bool ignore_case=true);
|
||||
|
||||
bool file_exists(const char *name);
|
||||
bool maketempname(char *ofilename, const char *ifilename,
|
||||
const char *ext, bool force=true);
|
||||
bool makebakname(char *ofilename, const char *ifilename, bool force=true);
|
||||
bool maketempname(char *ofilename, size_t size,
|
||||
const char *ifilename, const char *ext, bool force=true);
|
||||
bool makebakname(char *ofilename, size_t size,
|
||||
const char *ifilename, bool force=true);
|
||||
bool isafile(int fd);
|
||||
|
||||
unsigned get_ratio(unsigned u_len, unsigned c_len);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#define UPX_VERSION_HEX 0x019001 /* 01.90.01 */
|
||||
#define UPX_VERSION_STRING "1.90.1"
|
||||
#define UPX_VERSION_STRING4 "1.90"
|
||||
#define UPX_VERSION_DATE "Jul 16th 2002"
|
||||
#define UPX_VERSION_DATE "Sep 9th 2002"
|
||||
|
||||
14
src/work.cpp
14
src/work.cpp
@ -31,7 +31,6 @@
|
||||
#include "packmast.h"
|
||||
#include "packer.h"
|
||||
#include "ui.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
#if defined(__DJGPP__)
|
||||
@ -114,7 +113,7 @@ void do_one_file(const char *iname, char *oname)
|
||||
strcpy(tname,opt->output_name);
|
||||
else
|
||||
{
|
||||
if (!maketempname(tname,iname,".upx"))
|
||||
if (!maketempname(tname, sizeof(tname), iname, ".upx"))
|
||||
throwIOException("could not create a temporary file name");
|
||||
}
|
||||
if (opt->force >= 2)
|
||||
@ -201,7 +200,7 @@ void do_one_file(const char *iname, char *oname)
|
||||
{
|
||||
// make backup
|
||||
char bakname[PATH_MAX+1];
|
||||
if (!makebakname(bakname,iname))
|
||||
if (!makebakname(bakname, sizeof(bakname), iname))
|
||||
throwIOException("could not create a backup file name");
|
||||
File::rename(iname,bakname);
|
||||
}
|
||||
@ -264,10 +263,6 @@ void do_files(int i, int argc, char *argv[])
|
||||
|
||||
for ( ; i < argc; i++)
|
||||
{
|
||||
#if defined(WITH_MSS)
|
||||
//MSS_ENABLE_LOG_OUTPUT;
|
||||
//MSS_ENTER_SCOPE;
|
||||
#endif
|
||||
infoHeader();
|
||||
|
||||
const char *iname = argv[i];
|
||||
@ -308,11 +303,6 @@ void do_files(int i, int argc, char *argv[])
|
||||
printUnhandledException(iname,NULL);
|
||||
e_exit(EXIT_ERROR);
|
||||
}
|
||||
|
||||
#if defined(WITH_MSS)
|
||||
//MSS_LEAVE_SCOPE;
|
||||
MSS_CHECK_ALL_BLOCKS;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (opt->cmd == CMD_COMPRESS)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user