From ce7e94030cbe80033cf67003299a2c5c802947ff Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Fri, 16 Feb 2007 08:52:31 +0100 Subject: [PATCH] Added i086/l_test.c. Cleanups. --- src/stub/Makefile | 1 + src/stub/src/arch/i086/Makefile.extra | 111 ++++++++++++++++------ src/stub/src/arch/i086/cc_test.c | 3 + src/stub/src/arch/i086/l_test.c | 127 ++++++++++++++++++++++++++ src/stub/src/arch/i086/lzma_d.S | 32 ++++++- src/stub/src/arch/i086/nrv2b_d16.S | 5 +- src/stub/src/arch/i086/nrv2b_d8.S | 2 +- src/stub/src/arch/i086/nrv2d_d8.S | 2 +- src/stub/src/arch/i086/nrv2e_d8.S | 3 +- src/stub/src/c/lzma_d_c.c | 2 + 10 files changed, 250 insertions(+), 38 deletions(-) create mode 100644 src/stub/src/arch/i086/l_test.c diff --git a/src/stub/Makefile b/src/stub/Makefile index 06547e4e..f70e45d9 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -211,6 +211,7 @@ endef # some common arch settings tc.arch-i086.gcc = i386-linux-gcc-3.4.6 -m32 -march=i386 -nostdinc -MMD -MT $@ +tc.arch-i086.wdis = $(WATCOM)/binl/wdis tc.arch-i386.gcc = i386-linux-gcc-3.4.6 -m32 -march=i386 -nostdinc -MMD -MT $@ tc.arch-i386.djasm = djasm diff --git a/src/stub/src/arch/i086/Makefile.extra b/src/stub/src/arch/i086/Makefile.extra index 163d3003..23283690 100644 --- a/src/stub/src/arch/i086/Makefile.extra +++ b/src/stub/src/arch/i086/Makefile.extra @@ -32,12 +32,12 @@ include $(top_srcdir)/src/stub/Makefile # // method-lzma # ************************************************************************/ -lzma_d_c% : tc_list = method-lzma default +lzma_d_c% : tc_list = method-lzma arch-i086 default lzma_d_c% : tc_bfdname = # Open Watcom C/C++ 1.6 -c := tc.method-lzma.wcc -$c = $(WATCOM)/binl/wcc -zq -bt=dos +c := tc.method-lzma.wcl +$c = PATH='$(WATCOM)/binl:$(PATH)' $(WATCOM)/binl/wcl -zq -bt=dos $c += -mc -ecc $c += -zm -zc $c += -os -s -0 -d0 @@ -47,7 +47,6 @@ $c += -I$(UPX_LZMADIR) $c += -I$(top_srcdir)/src tc.method-lzma.dmpobj = $(WATCOM)/binl/dmpobj -tc.method-lzma.wdis = $(WATCOM)/binl/wdis tc.method-lzma.wdump = $(WATCOM)/binl/wdump lzma_d_c%.S : lzma_d_c%.i cleanasm.py $(MAKEFILE_LIST) @@ -55,19 +54,23 @@ lzma_d_c%.S : lzma_d_c%.i cleanasm.py $(MAKEFILE_LIST) ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),) ifneq ($(wildcard $(WATCOM)/binl/.),) +ifneq ($(wildcard /usr/bin/wine),) ifneq ($(wildcard $(VCLINK.exe)),) -lzma_d_c%.i : lzma_d_c.c tmp/.tmp-stamp $(MAKEFILE_LIST) +lzma_d_c%.i : lzma_d_c.c $(MAKEFILE_LIST) $(TMP_DEPS) rm -f tmp/$T.a tmp/$T.o tmp/$T.obj # compile - $(call tc,wcc) $(PP_FLAGS) -fo=tmp/$T.obj $< -## $(call tc,bcc) $(PP_FLAGS) -c -otmp/$T.obj $< -## $(call tc,dmc) $(PP_FLAGS) -c -otmp/$T.obj $< -## $(call tc,cl) $(PP_FLAGS) -c -Fotmp/$T.obj $< - $(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm + $(call tc,wcl) $(PP_FLAGS) -c -fo=tmp/$T_wc.obj $< + $(call tc,wdis) tmp/$T_wc.obj | $(RTRIM) > tmp/$T.obj.disasm +## $(call tc,bcc) $(PP_FLAGS) -c -otmp/$T_bc.obj $< +## $(call tc,wdis) tmp/$T_bc.obj | $(RTRIM) > tmp/$T_bc.obj.disasm + $(call tc,dmc) $(PP_FLAGS) -c -otmp/$T_dm.obj $< + $(call tc,wdis) tmp/$T_dm.obj | $(RTRIM) > tmp/$T_dm.obj.disasm + $(call tc,cl) $(PP_FLAGS) -c -Fotmp/$T_vc.obj $< + $(call tc,wdis) tmp/$T_vc.obj | $(RTRIM) > tmp/$T_vc.obj.disasm # convert OMF to COFF because objdump does not support OMF # TODO: should write a Python script wdis2gas.py and use that instead - cp -p tmp/$T.obj tmp/$T.o + cp -p tmp/$T_wc.obj tmp/$T.o cd tmp && $(WINEENV) wine $(VCLINK.exe) -lib -nologo -out:$T.a $T.o cd tmp && $(call tc,m-ar) x $T.a # dump @@ -78,23 +81,29 @@ lzma_d_c%.i : lzma_d_c.c tmp/.tmp-stamp $(MAKEFILE_LIST) endif endif endif +endif lzma_d_cf.% : PP_FLAGS = -DFAST lzma_d_cs.% : PP_FLAGS = -DSMALL lzma_d_cf.% : LABEL_PREFIX = .Lf lzma_d_cs.% : LABEL_PREFIX = .Ls +TMP_DEPS = tmp/.tmp-stamp tmp/bcc.bat tmp/cl.bat tmp/dmc.bat + # /*********************************************************************** # // cc_test # ************************************************************************/ +CC_TEST_DEPS = $(MAKEFILE_LIST) $(TMP_DEPS) WINEENV = env WINEENV = env -i DISPLAY='$(DISPLAY)' HOME='$(HOME)' PATH='$(PATH)' USER='$(USER)' # work around limitations of wine's cmd.exe define mkbat echo -E '@set PATH=$3;%PATH%' > $1 + echo -E '@set INCLUDE=$4' >> $1 + echo -E '@set LIB=$5' >> $1 echo -E '@set a=%1 %2 %3 %4 %5 %6 %7 %8 %9' >> $1 echo -e '@shift\n@shift\n@shift\n@shift\n@shift' >> $1 echo -e '@shift\n@shift\n@shift\n@shift' >> $1 @@ -105,6 +114,19 @@ define mkbat unix2dos -q $1 endef +tmp/bcc.bat: tmp/.tmp-stamp $(MAKEFILE_LIST) + @$(call mkbat,$@,bcc.exe,$(BC502WINDIR)\bin,,) +tmp/cl.bat: tmp/.tmp-stamp $(MAKEFILE_LIST) + @$(call mkbat,$@,cl.exe,$(VC152WINDIR)\bin,$(VC152WINDIR)\include,$(VC152WINDIR)\lib) +tmp/dmc.bat: tmp/.tmp-stamp $(MAKEFILE_LIST) + @$(call mkbat,$@,dmc.exe,$(DM847WINDIR)\bin,,) + +# gcc +c := tc.arch-i386.gcc +$c += -Wall -W +$c += -I$(UPX_LZMADIR) +$c += -I$(top_srcdir)/src + # Borland C/C++ 5.02 ifneq ($(wildcard $(BC502DIR)/bin/.),) c := tc.method-lzma.bcc @@ -119,10 +141,11 @@ $c += -I$(top_srcdir)/src endif # Digital Mars C/C++ 8.47 +# http://www.digitalmars.com/download/freecompiler.html ifneq ($(wildcard $(DM847DIR)/bin/.),) c := tc.method-lzma.dmc $c = @$(WINEENV) CFLAGS='$(DMC)' wine cmd.exe /c tmp/dmc.bat -$c += -mc +$c += -ms $c += -NS $c += -w- DMC := -o -0 @@ -135,9 +158,9 @@ endif ifneq ($(wildcard $(VC152DIR)/bin/.),) c := tc.method-lzma.cl $c = @$(WINEENV) CL='$(CL)' wine cmd.exe /c tmp/cl.bat -$c += -AC +$c += -AS -Gd $c += -Gy -$c += -O1 -Gf -Gs -G0 +$c += -O2 -Gf -Gs -G0 $c += -W4 CL := -nologo CL += -D__INT_MAX__=32767 @@ -147,40 +170,70 @@ endif ifneq ($(wildcard $(WATCOM)/binl/.),) -cc_test_wc : tc_list = method-lzma default -cc_test_wc: cc_test.c - $(call tc,wcc) $(PP_FLAGS) -fo=tmp/$T.obj $< +cc_test_wc : tc_list = method-lzma arch-i086 default +cc_test_wc: cc_test.c $(CC_TEST_DEPS) + $(call tc,wcl) $(PP_FLAGS) -c -fo=tmp/$T.obj $< $(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm ## cat tmp/$T.obj.disasm endif ifneq ($(wildcard $(BC502DIR)/bin/.),) -tmp/bcc.bat: tmp/.tmp-stamp $(MAKEFILE_LIST) - @$(call mkbat,$@,bcc.exe,$(BC502WINDIR)\\bin) -cc_test_bc : tc_list = method-lzma default -cc_test_bc: cc_test.c tmp/bcc.bat +cc_test_bc : tc_list = method-lzma arch-i086 default +cc_test_bc: cc_test.c $(CC_TEST_DEPS) $(call tc,bcc) $(PP_FLAGS) -c -otmp/$T.obj $< $(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm ## cat tmp/$T.obj.disasm endif ifneq ($(wildcard $(DM847DIR)/bin/.),) -tmp/dmc.bat: tmp/.tmp-stamp $(MAKEFILE_LIST) - @$(call mkbat,$@,dmc.exe,$(DM847WINDIR)\\bin) -cc_test_dm : tc_list = method-lzma default -cc_test_dm: cc_test.c tmp/dmc.bat +cc_test_dm : tc_list = method-lzma arch-i086 default +cc_test_dm: cc_test.c $(CC_TEST_DEPS) $(call tc,dmc) $(PP_FLAGS) -c -otmp/$T.obj $< $(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm ## cat tmp/$T.obj.disasm endif ifneq ($(wildcard $(VC152DIR)/bin/.),) -tmp/cl.bat: tmp/.tmp-stamp $(MAKEFILE_LIST) - @$(call mkbat,$@,cl.exe,$(VC152WINDIR)\\bin) -cc_test_vc : tc_list = method-lzma default -cc_test_vc: cc_test.c tmp/cl.bat +cc_test_vc : tc_list = method-lzma arch-i086 default +cc_test_vc: cc_test.c $(CC_TEST_DEPS) $(call tc,cl) $(PP_FLAGS) -c -Fotmp/$T.obj $< $(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm ## cat tmp/$T.obj.disasm endif + +# /*********************************************************************** +# // l_test +# ************************************************************************/ + +L_TEST_DEPS = lzma_d_c.c $(MAKEFILE_LIST) $(TMP_DEPS) +DOSBOX = /usr/bin/time -v dosbox -exit +DOSBOX = dosbox + +tmp/l_t_gcc_i386.% : tc_list = arch-i386 default +tmp/l_t_gcc_i386.out: l_test.c $(L_TEST_DEPS) + $(call tc,gcc) -O0 -g -o $@ $< + ./$@ + +tmp/l_t_bc.% : tc_list = method-lzma arch-i086 default +tmp/l_t_bc.exe: l_test.c $(L_TEST_DEPS) + $(call tc,bcc) -o$(subst /,\\,$@) $< + $(DOSBOX) $@ + +tmp/l_t_dm.% : tc_list = method-lzma arch-i086 default +tmp/l_t_dm.exe: l_test.c $(L_TEST_DEPS) + $(call tc,dmc) -ml -o$(subst /,\\,$@) $< + $(DOSBOX) $@ + +tmp/l_t_wc.% : tc_list = method-lzma arch-i086 default +tmp/l_t_wc.exe: l_test.c $(L_TEST_DEPS) + $(call tc,wcl) -fe=$@ $< + $(DOSBOX) $@ + +tmp/l_t_vc.% : tc_list = method-lzma arch-i086 default +tmp/l_t_vc.exe: l_test.c $(L_TEST_DEPS) + $(call tc,cl) -Fe$(subst /,\\,$@) $< + $(DOSBOX) $@ + +.PHONY: tmp/l_t_gcc_i386.out tmp/l_t_bc.exe tmp/l_t_dm.exe tmp/l_t_wc.exe tmp/l_t_vc.exe + diff --git a/src/stub/src/arch/i086/cc_test.c b/src/stub/src/arch/i086/cc_test.c index b60d3fea..a945a33a 100644 --- a/src/stub/src/arch/i086/cc_test.c +++ b/src/stub/src/arch/i086/cc_test.c @@ -103,6 +103,9 @@ void __pascal p4fshlv_v(unsigned char v, uint32_t __far *a) { *a <<= v; } uint32_t __pascal p4nshlv(unsigned char v, uint32_t __near *a) { return *a <<= v; } uint32_t __pascal p4fshlv(unsigned char v, uint32_t __far *a) { return *a <<= v; } +uint32_t __cdecl shlv_2(uint16_t h, uint16_t l, unsigned v) +{ uint16_t x = l >> (16 - v); l <<= v; h <<= v; h |= x; return h * 65536ul + l; } + hptrdiff_t __cdecl hptr2int(hptr a) { return (hptrdiff_t) a; } hptr __cdecl int2hptr(hptrdiff_t a) { return (hptr) a; } diff --git a/src/stub/src/arch/i086/l_test.c b/src/stub/src/arch/i086/l_test.c new file mode 100644 index 00000000..8e82afd7 --- /dev/null +++ b/src/stub/src/arch/i086/l_test.c @@ -0,0 +1,127 @@ +/* l_test.c -- + + This file is part of the UPX executable compressor. + + Copyright (C) 2007-2007 Markus Franz Xaver Johannes Oberhumer + 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 + + */ + + +#include "stub/src/c/lzma_d_c.c" + +#if (ACC_ARCH_I086) +#define bytep unsigned char __huge * +typedef unsigned long uint32_t; +#else +#define bytep unsigned char * +typedef unsigned int uint32_t; +#endif + + +#if (ACC_OS_DOS16) +# if (ACC_CC_BORLANDC || ACC_CC_TURBOC) + int __cdecl printf(const char *, ...); + void * __cdecl malloc(unsigned); + void __far * __cdecl farmalloc(unsigned long); +# define acc_halloc(x) ((void __huge *) farmalloc(x)) +# elif (ACC_CC_DMC || ACC_CC_MSC) +# include +# include +# define acc_halloc(x) _halloc(x,1) +# elif (ACC_CC_WATCOMC) + int __watcall printf(const char *, ...); + void * __watcall malloc(unsigned); + void __huge * __watcall halloc(long, unsigned); +# define acc_halloc(x) halloc(x,1) +# else +# endif +#else +# define printf __builtin_printf +# define malloc(x) __builtin_malloc(x) +# define acc_halloc(x) malloc(x) +#endif + + +/************************************************************************* +// +**************************************************************************/ + +/* +>>> import pylzma; d="\1" + "\0"*131070 + "\2"; print len(d) +>>> c=pylzma.compress(d, eos=0)[5:]; print len(c), map(ord, c) +*/ +static const unsigned char c_data[96] = { +0, 0, 128, 65, 72, 1, 140, 46, 188, 80, 161, 51, 135, 75, 212, 2, 20, 181, 241, 145, 230, 34, 107, 72, 201, 86, 118, 176, 70, 120, 214, 184, 247, 212, 250, 132, 59, 160, 44, 112, 185, 177, 245, 126, 103, 190, 14, 145, 73, 36, 148, 246, 166, 58, 41, 192, 68, 167, 144, 98, 122, 42, 61, 195, 135, 248, 98, 136, 254, 191, 96, 21, 192, 75, 86, 63, 228, 231, 15, 70, 52, 239, 169, 194, 249, 109, 126, 11, 123, 48, 0, 0 +}; + + + +int main() +{ + uint32_t i; + int r; + uint32_t src_len = sizeof(c_data); + uint32_t dst_len = 131072ul; + uint32_t src_out = 0; + uint32_t dst_out = 0; + const bytep src; + bytep dst; + CLzmaDecoderState *s; + + printf("Decompress %lu %lu\n", (long)src_len, (long)dst_len); + s = (CLzmaDecoderState *) malloc(32768u); + src = c_data; + dst = (bytep) acc_halloc(dst_len); + if (!s || !dst) { + printf("ERROR: Out of memory!\n"); + return 1; + } + for (i = 0; i != dst_len; ++i) + dst[i] = 255; + + s->Properties.lc = 3; s->Properties.lp = 0; s->Properties.pb = 2; + r = LzmaDecode(s, src, src_len, &src_out, dst, dst_len, &dst_out); + + if (r != 0 || src_out > src_len || dst_out != dst_len) + { + printf("ERROR: Decompression error %d %lu %lu\n", r, (long)src_out, (long)dst_out); + return 1; + } + + i = 0; + if (dst[i] != 1) + goto data_error; + while (++i != dst_len - 1) + if (dst[i] != 0) + goto data_error; + if (dst[i] != 2) + goto data_error; + + printf("Decompression test passed. All done.\n"); + return 0; + +data_error: + printf("ERROR: Decompression data error at offset %lu.\n", (long)i); + return 1; +} + + +/* vim:set ts=4 et: */ diff --git a/src/stub/src/arch/i086/lzma_d.S b/src/stub/src/arch/i086/lzma_d.S index ea96bc62..1acd3f69 100644 --- a/src/stub/src/arch/i086/lzma_d.S +++ b/src/stub/src/arch/i086/lzma_d.S @@ -88,6 +88,21 @@ L1: .endm +// shld: dx:ax <<= cl; trashes register "r1" (bx, di, si or bp) +// REQUIRED: 0 <= cl < 32 +// FIXME - this does not work yet +.macro M_shld r1 + local L1 + mov r1, ax // save ax + shl dx, cl + shl ax, cl + neg cl + and cl, 15 // the 8086 uses all eight bits of the shift count + shr r1, cl + or dx, r1 +.endm + + /************************************************************************* // support code (see cleanasm.py) **************************************************************************/ @@ -196,11 +211,12 @@ section LZMA_DEC00 mov bp, sp lea bx, [bp + lzma_stack_adjust] #if 0 + // clear stack xor ax, ax -.clearstack: +1: push ax cmp sp, bx - jnz .clearstack + jnz 1b #else mov sp, bx #endif @@ -250,6 +266,16 @@ section LZMA_DEC20 // cleanup section LZMA_DEC30 +#if 0 + // clear dirty stack + lea bx, [bp + lzma_stack_adjust - 128] + mov sp, bp + xor ax, ax +1: + push ax + cmp sp, bx + jnz 1b +#endif mov sp, bp mov di, offset lzma_u_len @@ -267,5 +293,5 @@ section LZMA_DEC31 #undef WCC_PIA_V02 #undef WCC_PTS -// vi:ts=8:et +// vi:ts=4:et diff --git a/src/stub/src/arch/i086/nrv2b_d16.S b/src/stub/src/arch/i086/nrv2b_d16.S index dc4ba926..e9fe6d8d 100644 --- a/src/stub/src/arch/i086/nrv2b_d16.S +++ b/src/stub/src/arch/i086/nrv2b_d16.S @@ -105,6 +105,5 @@ decomp_done_n2b: cjt16 decomp_ret_n2b -/* -; vi:ts=8:et -*/ + +/* vim:set ts=4 et: */ diff --git a/src/stub/src/arch/i086/nrv2b_d8.S b/src/stub/src/arch/i086/nrv2b_d8.S index d56baa94..b604e812 100644 --- a/src/stub/src/arch/i086/nrv2b_d8.S +++ b/src/stub/src/arch/i086/nrv2b_d8.S @@ -152,5 +152,5 @@ f2_n2b: ret decomp_done_n2b: -/* vi:ts=8:et */ +/* vim:set ts=4 et: */ diff --git a/src/stub/src/arch/i086/nrv2d_d8.S b/src/stub/src/arch/i086/nrv2d_d8.S index 0354cbb1..1c26970f 100644 --- a/src/stub/src/arch/i086/nrv2d_d8.S +++ b/src/stub/src/arch/i086/nrv2d_d8.S @@ -162,5 +162,5 @@ f2_n2d: ret decomp_done_n2d: -/* vi:ts=8:et */ +/* vim:set ts=4 et: */ diff --git a/src/stub/src/arch/i086/nrv2e_d8.S b/src/stub/src/arch/i086/nrv2e_d8.S index 4cda1bdd..2779ecf1 100644 --- a/src/stub/src/arch/i086/nrv2e_d8.S +++ b/src/stub/src/arch/i086/nrv2e_d8.S @@ -168,4 +168,5 @@ f2_n2e: ret decomp_done_n2e: -/* vi:ts=8:et */ + +/* vim:set ts=4 et: */ diff --git a/src/stub/src/c/lzma_d_c.c b/src/stub/src/c/lzma_d_c.c index 68584726..759507f7 100644 --- a/src/stub/src/c/lzma_d_c.c +++ b/src/stub/src/c/lzma_d_c.c @@ -98,6 +98,8 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(SizeT) >= 4) #else #include "C/7zip/Compress/LZMA_C/LzmaDecode.c" #endif +#undef char +#undef CLzmaDecoderState #endif