Big re-sync with UPX 1.2 branch.
committer: mfx <mfx> 1026839174 +0000
This commit is contained in:
+245
-77
@@ -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,19 +21,21 @@
|
||||
; 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>
|
||||
;
|
||||
|
||||
|
||||
#define NRV_BB 8
|
||||
#include "../version.h"
|
||||
|
||||
|
||||
;
|
||||
; see also:
|
||||
; mint/src/basepage.h
|
||||
; mint/src/mem.h (FILEHEAD)
|
||||
; mint/src/mem.c (load_region, load_and_reloc)
|
||||
; freemint/sys/mint/basepage.h
|
||||
; freemint/sys/mint/mem.h (FILEHEAD)
|
||||
; freemint/sys/memory.c (load_region, load_and_reloc)
|
||||
; freemint/sys/arch/cpu.S (cpush)
|
||||
;
|
||||
|
||||
;
|
||||
@@ -80,19 +82,6 @@ p_parent equ $24 ; .l pointer to parent's basepage
|
||||
p_flags equ $28 ; .l memory usage flags
|
||||
p_env equ $2c ; .l pointer to environment string
|
||||
|
||||
#if 0
|
||||
; file header offsets (NOT USED)
|
||||
fh_magic equ $0 ; .w $601a
|
||||
fh_text equ $2 ; .l
|
||||
fh_data equ $6 ; .l
|
||||
fh_bss equ $a ; .l
|
||||
fh_sym equ $e ; .l
|
||||
fh_reserved equ $12 ; .l
|
||||
fh_flag equ $16 ; .l
|
||||
fh_reloc equ $1a ; .w
|
||||
FH_SIZE equ $1c ; 28 bytes
|
||||
#endif
|
||||
|
||||
;
|
||||
; long living registers:
|
||||
; d4 p_tbase - start of text segment
|
||||
@@ -100,10 +89,115 @@ FH_SIZE equ $1c ; 28 bytes
|
||||
; - end of decompressed text+data
|
||||
; - start of decompressed relocations
|
||||
; - start of dirty bss
|
||||
; a5 final startup code copied below stack
|
||||
; ASTACK (a7) - final startup code copied below stack
|
||||
;
|
||||
|
||||
|
||||
; /*************************************************************************
|
||||
; // flush cache macros
|
||||
; **************************************************************************/
|
||||
|
||||
; note:
|
||||
; GEMDOS/XBIOS trashes d0, d1, d2, a0, a1, a2
|
||||
|
||||
|
||||
; Ssystem(S_FLUSHCACHE, base, length) - inside the kernel this
|
||||
; is called `cpush(base, length)'.
|
||||
; returns: d0.l should be either 0 or -32 (== ENOSYS == EINVFN)
|
||||
; Available since FreeMiNT 1.15.1 (1999-04-13).
|
||||
;
|
||||
; Note that on a 68060 FreeMiNT just uses `cpusha bc' in all cases,
|
||||
; so we don't bother passing base and length. (info: base would be d4)
|
||||
|
||||
macro(MINT_FLUSH_CACHE)
|
||||
pea -1 ; length
|
||||
clr.l -(sp) ; base
|
||||
#if 0
|
||||
move.w #$0016,-(sp) ; S_FLUSHCACHE (22)
|
||||
move.w #$0154,-(sp) ; Ssystem (340)
|
||||
#else
|
||||
move.l #$01540016,-(sp)
|
||||
#endif
|
||||
trap #1 ; GEMDOS
|
||||
lea 12(sp),sp
|
||||
endm
|
||||
|
||||
|
||||
; First try `cpusha bc' (68040/68060). If that fails try temporary changing
|
||||
; the cache control register (68030).
|
||||
|
||||
macro(SUPEXEC_FLUSH_CACHE)
|
||||
pea \@super(pc)
|
||||
move.w #38,-(sp) ; Supexec
|
||||
trap #14 ; XBIOS
|
||||
addq.l #6,sp
|
||||
bra \@done
|
||||
|
||||
|
||||
; exception handler
|
||||
\@exception: move.l a1,sp ; restore stack (SSP)
|
||||
jmp (a0) ; and continue
|
||||
|
||||
|
||||
\@super: move.l ($10),-(sp)
|
||||
move.l ($2c),-(sp)
|
||||
move.l ($f4),-(sp)
|
||||
move.l sp,a1 ; save stack pointer (SSP)
|
||||
|
||||
; set exception vectors
|
||||
lea \@exception(pc),a0
|
||||
move.l a0,($10)
|
||||
move.l a0,($2c)
|
||||
move.l a0,($f4)
|
||||
nop ; flush write pipeline
|
||||
|
||||
; try 68040 / 68060
|
||||
lea \@1(pc),a0
|
||||
dc.w $f4f8 ; cpusha bc
|
||||
bra \@ret
|
||||
\@1:
|
||||
; try 68030
|
||||
lea \@2(pc),a0
|
||||
dc.l $4e7a0002 ; movec.l cacr,d0
|
||||
move.l d0,d1
|
||||
or.w #$0808,d1
|
||||
dc.l $4e7b1002 ; movec.l d1,cacr
|
||||
dc.l $4e7b0002 ; movec.l d0,cacr
|
||||
;;; bra \@ret
|
||||
\@2:
|
||||
|
||||
\@ret: move.l (sp)+,($f4)
|
||||
move.l (sp)+,($2c)
|
||||
move.l (sp)+,($10)
|
||||
nop ; flush write pipeline
|
||||
rts
|
||||
|
||||
\@done:
|
||||
endm
|
||||
|
||||
|
||||
|
||||
macro(BOTH_FLUSH_CACHE)
|
||||
MINT_FLUSH_CACHE
|
||||
tst.w d0
|
||||
beq \@done
|
||||
SUPEXEC_FLUSH_CACHE
|
||||
\@done:
|
||||
endm
|
||||
|
||||
|
||||
|
||||
#define ASTACK a7
|
||||
|
||||
#if 1
|
||||
# define FLUSH_CACHE BOTH_FLUSH_CACHE
|
||||
#elif 0
|
||||
# define FLUSH_CACHE MINT_FLUSH_CACHE
|
||||
#else
|
||||
# undef FLUSH_CACHE
|
||||
#endif
|
||||
|
||||
|
||||
; /*************************************************************************
|
||||
; // entry - the text segment of a compressed executable
|
||||
; //
|
||||
@@ -130,7 +224,7 @@ L(start): movem.l d1-d7/a0-a6,-(sp)
|
||||
|
||||
; ------------- restore original basepage
|
||||
|
||||
; we also setup d4, a6 and a1 here
|
||||
; we also setup d4 and a6 here, and we prepare a4
|
||||
|
||||
move.l d0,a2 ; a2 = basepage
|
||||
addq.l #p_tbase,a2
|
||||
@@ -141,24 +235,24 @@ L(start): movem.l d1-d7/a0-a6,-(sp)
|
||||
move.l a6,(a2)+ ; p_dbase
|
||||
move.l #'up12',(a2) ; p_dlen
|
||||
add.l (a2)+,a6 ; a6 = decompressed p_bbase
|
||||
move.l (a2),a1 ; a1 = compressed p_bbase
|
||||
move.l (a2),a4 ; a4 = compressed p_bbase
|
||||
move.l a6,(a2)+ ; p_bbase
|
||||
move.l #'up13',(a2) ; p_blen
|
||||
|
||||
|
||||
; ------------- copy data segment (from a1 to a0, downwards)
|
||||
; ------------- copy data segment (from a4 to a3, downwards)
|
||||
|
||||
; a1 (top of compressed data) already initialized above
|
||||
; a4 (top of compressed data) already initialized above
|
||||
|
||||
move.l d4,a0
|
||||
add.l #'up21',a0 ; top of data segment + offset
|
||||
move.l d4,a3
|
||||
add.l #'up21',a3 ; top of data segment + offset
|
||||
|
||||
#if defined(SMALL)
|
||||
|
||||
move.l #'up22',d0 ; (len / 4)
|
||||
|
||||
; copy 4 bytes per loop
|
||||
L(loop): move.l -(a1),-(a0)
|
||||
L(loop): move.l -(a4),-(a3)
|
||||
;;subq.l #1,d0
|
||||
dc.b 'u1' ; subq.l #1,d0 / subq.w #1,d0
|
||||
bne L(loop)
|
||||
@@ -169,15 +263,15 @@ L(loop): move.l -(a1),-(a0)
|
||||
|
||||
; loop1 - use 10 registers to copy 4*10*4 = 160 bytes per loop
|
||||
L(loop1):
|
||||
lea.l -160(a1),a1
|
||||
movem.l 120(a1),d1-d3/d5-d7/a2-a5
|
||||
movem.l d1-d3/d5-d7/a2-a5,-(a0)
|
||||
movem.l 80(a1),d1-d3/d5-d7/a2-a5
|
||||
movem.l d1-d3/d5-d7/a2-a5,-(a0)
|
||||
movem.l 40(a1),d1-d3/d5-d7/a2-a5
|
||||
movem.l d1-d3/d5-d7/a2-a5,-(a0)
|
||||
movem.l (a1),d1-d3/d5-d7/a2-a5
|
||||
movem.l d1-d3/d5-d7/a2-a5,-(a0)
|
||||
lea.l -160(a4),a4
|
||||
movem.l 120(a4),d1-d3/d5-d7/a0-a2/a5
|
||||
movem.l d1-d3/d5-d7/a0-a2/a5,-(a3)
|
||||
movem.l 80(a4),d1-d3/d5-d7/a0-a2/a5
|
||||
movem.l d1-d3/d5-d7/a0-a2/a5,-(a3)
|
||||
movem.l 40(a4),d1-d3/d5-d7/a0-a2/a5
|
||||
movem.l d1-d3/d5-d7/a0-a2/a5,-(a3)
|
||||
movem.l (a4),d1-d3/d5-d7/a0-a2/a5
|
||||
movem.l d1-d3/d5-d7/a0-a2/a5,-(a3)
|
||||
;;subq.l #1,d0
|
||||
dc.b 'u1' ; subq.l #1,d0 / subq.w #1,d0
|
||||
bne L(loop1)
|
||||
@@ -186,45 +280,63 @@ L(loop1):
|
||||
;;moveq.l #xx,d0 ; ((len % 160) / 4) - 1
|
||||
dc.b 'u2' ; moveq.l #xx,d0
|
||||
|
||||
L(loop2): move.l -(a1),-(a0)
|
||||
L(loop2): move.l -(a4),-(a3)
|
||||
dbra d0,L(loop2)
|
||||
|
||||
#endif
|
||||
|
||||
; a0 now points to the start of the compressed block
|
||||
; a3 now points to the start of the compressed block
|
||||
|
||||
|
||||
; ------------- copy code to stack and setup a5
|
||||
; ------------- copy code to stack and setup ASTACK
|
||||
|
||||
; Copy the final startup code below the stack. This will get
|
||||
; called via "jmp (a5)" after decompression and relocation.
|
||||
; called via "jmp (ASTACK)" after decompression and relocation.
|
||||
|
||||
copy_to_stack:
|
||||
lea.l clear_bss_end(pc),a2
|
||||
move.l sp,a5
|
||||
moveq.l #((clear_bss_end-clear_bss)/2-1),d5
|
||||
|
||||
move.l d4,-(a5) ; entry point for final jmp
|
||||
L(loop): move.w -(a2),-(a5)
|
||||
lea.l clear_bss_end(pc),a2
|
||||
move.l d4,-(ASTACK) ; entry point for final jmp
|
||||
|
||||
moveq.l #((clear_bss_end-clear_bss)/2-1),d5
|
||||
L(loop): move.w -(a2),-(ASTACK)
|
||||
subq.l #1,d5
|
||||
bcc L(loop)
|
||||
|
||||
#ifdef FLUSH_CACHE
|
||||
; patch code: on the stack, the `rts' becomes a `nop'
|
||||
move.w #$4e71,flush_cache_rts-clear_bss(ASTACK)
|
||||
#endif
|
||||
|
||||
; note: d5.l is now -1 (needed for decompressor)
|
||||
|
||||
|
||||
; -------------
|
||||
|
||||
#ifdef FLUSH_CACHE
|
||||
bsr flush_cache
|
||||
#endif
|
||||
|
||||
|
||||
; ------------- prepare decompressor
|
||||
|
||||
; a0 still points to the start of the compressed block
|
||||
move.l d4,a1 ; dest. for decompressing
|
||||
; a3 still points to the start of the compressed block
|
||||
move.l d4,a4 ; dest. for decompressing
|
||||
|
||||
#define NRV_NO_INIT
|
||||
|
||||
;;moveq.l #-1,d5 ; last_off = -1
|
||||
moveq.l #-1,d7
|
||||
moveq.l #-128,d0 ; d0.b = $80
|
||||
#if defined(NRV2B)
|
||||
moveq.l #-1,d7
|
||||
moveq.l #-$68,d6 ; 0xffffff98
|
||||
lsl.w #5,d6 ; 0xfffff300 == -0xd00
|
||||
#elif defined(NRV2D)
|
||||
moveq.l #-1,d7
|
||||
moveq.l #-$50,d6 ; 0xffffffb0
|
||||
lsl.w #4,d6 ; 0xfffffb00 == -0x500
|
||||
#elif defined(NRV2E)
|
||||
moveq.l #0,d7
|
||||
moveq.l #-$50,d6 ; 0xffffffb0
|
||||
lsl.w #4,d6 ; 0xfffffb00 == -0x500
|
||||
#endif
|
||||
@@ -245,26 +357,73 @@ L(loop): move.w -(a2),-(a5)
|
||||
|
||||
clear_bss:
|
||||
|
||||
; on entry d2 is 0
|
||||
; on entry:
|
||||
; ASTACK == pc == clear_bss (on stack)
|
||||
; a6 start of dirty bss [long living register]
|
||||
; d6.l number of clr loops
|
||||
; d3.l 0
|
||||
|
||||
|
||||
#if defined(SMALL)
|
||||
L(loop): move.l d2,(a6)+
|
||||
;;subq.l #1,d0
|
||||
dc.b 'u4' ; subq.l #1,d0 / subq.w #1,d0
|
||||
L(loop): move.l d3,(a6)+
|
||||
;;subq.l #1,d6
|
||||
dc.b 'u4' ; subq.l #1,d6 / subq.w #1,d6
|
||||
bne L(loop)
|
||||
#else
|
||||
; the dirty bss is usually not too large, so we don't
|
||||
; bother making movem optimizations here
|
||||
L(loop): move.l d2,(a6)+
|
||||
move.l d2,(a6)+
|
||||
move.l d2,(a6)+
|
||||
move.l d2,(a6)+
|
||||
;;subq.l #1,d0
|
||||
dc.b 'u4' ; subq.l #1,d0 / subq.w #1,d0
|
||||
L(loop): move.l d3,(a6)+
|
||||
move.l d3,(a6)+
|
||||
move.l d3,(a6)+
|
||||
move.l d3,(a6)+
|
||||
;;subq.l #1,d6
|
||||
dc.b 'u4' ; subq.l #1,d6 / subq.w #1,d6
|
||||
bne L(loop)
|
||||
#endif
|
||||
|
||||
|
||||
; ------------- flush the cache
|
||||
|
||||
#ifdef FLUSH_CACHE
|
||||
|
||||
; info:
|
||||
; This is also called as a subroutine (before decompression, NOT running
|
||||
; in the stack). When running in the stack the `rts' is replaced by a `nop'.
|
||||
;
|
||||
flush_cache:
|
||||
FLUSH_CACHE
|
||||
flush_cache_rts:
|
||||
rts
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
; ------------- restore ASTACK
|
||||
|
||||
lea clear_bss_end-clear_bss+4(ASTACK),sp
|
||||
|
||||
;; assert sp == clear_bss_end(pc)+4
|
||||
|
||||
|
||||
; ------------- clear the dirty stack
|
||||
|
||||
#if 0
|
||||
;;; /* 0 || defined(FLUSH_CACHE) */
|
||||
|
||||
; better don't do this - we are currently running in the stack
|
||||
; and don't want to make yet another instruction-cache-line dirty
|
||||
|
||||
clear_dirty_stack:
|
||||
|
||||
; clear down to clear_bss(pc) + 32 extra longs
|
||||
moveq.l #((L(loop)-clear_bss+3)/4+32-1),d0
|
||||
lea L(loop)(pc),a0
|
||||
L(loop): move.l d3,-(a0)
|
||||
dbra d0,L(loop)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
; ------------- start program
|
||||
|
||||
movem.l (sp)+,d1-d7/a0-a6
|
||||
@@ -288,11 +447,8 @@ clear_bss_end:
|
||||
|
||||
align4
|
||||
|
||||
; 32 bytes - #include "header.ash"
|
||||
dc.b 85,80,88,33 ; UPX_MAGIC_LE32
|
||||
dc.b 161,216,208,213 ; UPX_MAGIC2_LE32
|
||||
dc.l 0,0,0,0,0 ; 20 bytes
|
||||
dc.b 0,0,0,45
|
||||
dc.b 'UPX!' ; magic
|
||||
dc.l 0,0,0,0,0,0,0 ; 28 bytes - #include "header.ash"
|
||||
|
||||
|
||||
; end of text segment - size is a multiple of 4
|
||||
@@ -306,31 +462,43 @@ clear_bss_end:
|
||||
|
||||
cutpoint:
|
||||
|
||||
; ------------- decompress (from a0 to a1)
|
||||
; ------------- decompress (from a3 to a4)
|
||||
|
||||
#define a0 A3
|
||||
#define a1 A4
|
||||
#define a3 A2
|
||||
#define d2 D3
|
||||
|
||||
#if defined(NRV2B)
|
||||
# include "m68k/n2b_d.ash"
|
||||
#elif defined(NRV2D)
|
||||
# include "m68k/n2d_d.ash"
|
||||
#elif defined(NRV2E)
|
||||
# include "m68k/n2e_d.ash"
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
|
||||
; note: d2 is 0 from decompressor above
|
||||
#undef a0
|
||||
#undef a1
|
||||
#undef a3
|
||||
#undef d2
|
||||
|
||||
; note: d3.l is 0 from decompressor above
|
||||
|
||||
|
||||
; ------------- prepare d0 for clearing the dirty bss
|
||||
; ------------- prepare d6 for clearing the dirty bss
|
||||
|
||||
#if defined(SMALL)
|
||||
move.l #'up41',d0 ; dirty_bss / 4
|
||||
move.l #'up41',d6 ; dirty_bss / 4
|
||||
#else
|
||||
move.l #'up41',d0 ; dirty_bss / 16
|
||||
move.l #'up41',d6 ; dirty_bss / 16
|
||||
#endif
|
||||
|
||||
|
||||
; ------------- test if we need to reloc
|
||||
|
||||
dc.b 'u3' ; moveq.l #1,d3 / jmp (a5)
|
||||
dc.b 'u3' ; moveq.l #1,d5 / jmp (ASTACK)
|
||||
|
||||
|
||||
; ------------- reloc
|
||||
@@ -340,20 +508,20 @@ reloc:
|
||||
; The decompressed relocations now are just after the decompressed
|
||||
; data segment, i.e. at the beginning of the (dirty) bss.
|
||||
|
||||
; note: d2 is still 0
|
||||
; note: d3.l is still 0
|
||||
|
||||
move.l a6,a0 ; a0 = start of relocations
|
||||
|
||||
move.l d4,a1
|
||||
add.l (a0)+,a1 ; get initial fixup
|
||||
|
||||
L(loop1): add.l d2,a1 ; increase fixup
|
||||
L(loop1): add.l d3,a1 ; increase fixup
|
||||
add.l d4,(a1) ; reloc one address
|
||||
L(loop2): move.b (a0)+,d2
|
||||
L(loop2): move.b (a0)+,d3
|
||||
beq reloc_end
|
||||
cmp.b d3,d2 ; note: d3.b is #1
|
||||
cmp.b d5,d3 ; note: d5.b is #1 from above
|
||||
bne L(loop1)
|
||||
lea 254(a1),a1 ; d2 == 1 -> add 254, don't reloc
|
||||
lea 254(a1),a1 ; d3 == 1 -> add 254, don't reloc
|
||||
bra L(loop2)
|
||||
|
||||
reloc_end:
|
||||
@@ -364,9 +532,9 @@ reloc_end:
|
||||
; We are currently running in the dirty bss.
|
||||
; Jump to the code we copied below the stack.
|
||||
|
||||
; note: d2 is still 0
|
||||
; note: d3.l is still 0
|
||||
|
||||
jmp (a5) ; jmp clear_bss (on stack)
|
||||
jmp (ASTACK) ; jmp clear_bss (on stack)
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user