Initial commit (from git)
This commit is contained in:
@@ -0,0 +1,349 @@
|
||||
; l_tos.s -- loader & decompressor for the atari/tos format
|
||||
;
|
||||
; This file is part of the UPX executable compressor.
|
||||
;
|
||||
; Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer
|
||||
; Copyright (C) 1996-2000 Laszlo Molnar
|
||||
;
|
||||
; 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
|
||||
; markus.oberhumer@jk.uni-linz.ac.at ml1050@cdata.tvnet.hu
|
||||
;
|
||||
|
||||
|
||||
#define NRV_BB 8
|
||||
|
||||
|
||||
;
|
||||
; see also:
|
||||
; mint/src/basepage.h
|
||||
; mint/src/mem.h (FILEHEAD)
|
||||
; mint/src/mem.c (load_region, load_and_reloc)
|
||||
;
|
||||
|
||||
;
|
||||
; This file is first preprocessed by cpp, then the a68k assembler
|
||||
; is run and finally the generated object file is translated to a .h file
|
||||
; by a simple perl script. We also maintain compatiblity with the pasm
|
||||
; assembler (which must be started in the emulator window).
|
||||
;
|
||||
|
||||
|
||||
#ifdef __A68K__
|
||||
# define align4 align 0,4
|
||||
# define L(label) \/**/label
|
||||
# define macro(name) name macro
|
||||
# define text section code
|
||||
#else
|
||||
# define align4 align 4
|
||||
# define L(label) ./**/label
|
||||
# define macro(name) macro name
|
||||
#endif
|
||||
|
||||
; defines needed for including ident_[ns].ash
|
||||
#define db dc.b
|
||||
#define dw dc.w
|
||||
#define dd dc.l
|
||||
|
||||
|
||||
; basepage offsets
|
||||
p_lowtpa equ $0 ; .l
|
||||
p_hitpa equ $4 ; .l
|
||||
p_tbase equ $8 ; .l
|
||||
p_tlen equ $c ; .l
|
||||
p_dbase equ $10 ; .l
|
||||
p_dlen equ $14 ; .l
|
||||
p_bbase equ $18 ; .l
|
||||
p_blen equ $1c ; .l
|
||||
|
||||
#if 0
|
||||
; file header offsets (NOT USED)
|
||||
fh_branch equ $0 ; .w $601a
|
||||
fh_tlen equ $2 ; .l
|
||||
fh_dlen equ $6 ; .l
|
||||
fh_blen equ $a ; .l
|
||||
fh_slen equ $e ; .l
|
||||
fh_res1 equ $12 ; .l
|
||||
fh_res2 equ $16 ; .l
|
||||
fh_flag equ $1a ; .w
|
||||
|
||||
fh_size equ $1c ; 28 bytes
|
||||
#endif
|
||||
|
||||
;
|
||||
; long living registers:
|
||||
; d4 p_tbase - start of text segment
|
||||
; a6 p_bbase - start of uncompressed bss segment, this also is the
|
||||
; - end of decompressed text+data
|
||||
; - beginning of decompressed relocations
|
||||
; - beginning of dirty bss
|
||||
; a5 final startup code copied below stack
|
||||
;
|
||||
|
||||
|
||||
; /*************************************************************************
|
||||
; // entry - the text segment of a compressed executable
|
||||
; //
|
||||
; // note: compressed programs never have the F_SHTEXT flag set,
|
||||
; // so we can assume that the text, data & bss segments
|
||||
; // are contiguous in memory
|
||||
; **************************************************************************/
|
||||
|
||||
text
|
||||
dc.b 'UPX1' ; marker for o2bin.pl
|
||||
start:
|
||||
move.l a0,d0 ; a0 is basepage if accessory
|
||||
beq L(l_app)
|
||||
move.l 4(a0),sp ; accessory - get stack
|
||||
bra L(start)
|
||||
L(l_app): move.l 4(sp),d0 ; application - get basepage
|
||||
L(start): movem.l d1-d7/a0-a6,-(sp)
|
||||
|
||||
|
||||
; ------------- restore original basepage
|
||||
|
||||
; we also setup d4, a6 and a1 here
|
||||
|
||||
move.l d0,a2 ; a2 = basepage
|
||||
addq.l #p_tbase,a2
|
||||
move.l (a2)+,a6
|
||||
move.l a6,d4 ; d4 = p_tbase
|
||||
move.l #'up11',(a2) ; p_tlen
|
||||
add.l (a2)+,a6
|
||||
move.l a6,(a2)+ ; p_dbase
|
||||
move.l #'up12',(a2) ; p_dlen
|
||||
add.l (a2)+,a6 ; a6 = uncompressed p_bbase
|
||||
move.l (a2),a1 ; a1 = compressed p_bbase
|
||||
move.l a6,(a2)+ ; p_bbase
|
||||
move.l #'up13',(a2) ; p_blen
|
||||
|
||||
|
||||
; ------------- copy data segment (from a1 to a0, downwards)
|
||||
|
||||
; a1 (top of compressed data) already initialized above
|
||||
|
||||
move.l d4,a0
|
||||
add.l #'up21',a0 ; 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)
|
||||
;;subq.l #1,d0
|
||||
dc.b 'u1' ; subq.l #1,d0 / subq.w #1,d0
|
||||
bne L(loop)
|
||||
|
||||
#else
|
||||
|
||||
move.l #'up22',d0 ; (len / 160)
|
||||
|
||||
; 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)
|
||||
;;subq.l #1,d0
|
||||
dc.b 'u1' ; subq.l #1,d0 / subq.w #1,d0
|
||||
bne L(loop1)
|
||||
|
||||
; loop2 - copy the remaining 4..160 bytes
|
||||
;;moveq.l #xx,d0 ; ((len % 160) / 4) - 1
|
||||
dc.b 'u2' ; moveq.l #xx,d0
|
||||
|
||||
L(loop2): move.l -(a1),-(a0)
|
||||
dbra d0,L(loop2)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
; ------------- copy code to stack
|
||||
|
||||
; Copy the final startup code below the stack. This will get
|
||||
; called via "jmp (a5)" 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),d0
|
||||
|
||||
move.l d4,-(a5) ; entry point for final jmp
|
||||
L(loop): move.w -(a2),-(a5)
|
||||
subq.w #1,d0
|
||||
bne L(loop)
|
||||
|
||||
; note: now d0 is 0
|
||||
|
||||
|
||||
; ------------- prepare decompressor
|
||||
|
||||
; a0 now points to the start of the compressed block
|
||||
; note: the next statement can be moved below cutpoint
|
||||
; if it helps for the align4
|
||||
;;move.l d4,a1 ; dest. for uncompressing
|
||||
move.l d4,a1 ; dest. for uncompressing
|
||||
|
||||
|
||||
; ------------- jump to copied decompressor
|
||||
|
||||
move.l d4,a2
|
||||
add.l #'up31',a2
|
||||
jmp (a2) ; jmp cutpoint
|
||||
|
||||
|
||||
; /*************************************************************************
|
||||
; // this is the final part of the startup code which runs in the stack
|
||||
; **************************************************************************/
|
||||
|
||||
; on entry d1 and d2 are 0
|
||||
|
||||
; ------------- clear dirty bss
|
||||
|
||||
clear_bss:
|
||||
|
||||
#if defined(SMALL)
|
||||
L(loop): move.l d1,(a6)+
|
||||
;;subq.l #1,d0
|
||||
dc.b 'u4' ; subq.l #1,d0 / subq.w #1,d0
|
||||
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 d1,(a6)+
|
||||
move.l d1,(a6)+
|
||||
move.l d1,(a6)+
|
||||
move.l d1,(a6)+
|
||||
;;subq.l #1,d0
|
||||
dc.b 'u4' ; subq.l #1,d0 / subq.w #1,d0
|
||||
bne L(loop)
|
||||
#endif
|
||||
|
||||
|
||||
; ------------- start program
|
||||
|
||||
; note: d0.l is now 0
|
||||
|
||||
movem.l (sp)+,d1-d7/a0-a6
|
||||
cmp.l d0,a0
|
||||
beq L(l_app)
|
||||
;;suba.l sp,sp ; accessory: no stack
|
||||
move.l d0,sp ; accessory: no stack
|
||||
L(l_app): dc.w $4ef9 ; jmp $xxxxxxxx - jmp to text segment
|
||||
|
||||
clear_bss_end:
|
||||
|
||||
|
||||
; /*************************************************************************
|
||||
; // UPX ident & packheader
|
||||
; **************************************************************************/
|
||||
|
||||
#if defined(SMALL)
|
||||
# include "ident_s.ash"
|
||||
#else
|
||||
# include "ident_n.ash"
|
||||
#endif
|
||||
even
|
||||
|
||||
align4
|
||||
|
||||
dc.b 'UPX!' ; magic
|
||||
ds.b 28 ; #include "header.ash"
|
||||
|
||||
|
||||
; end of text segment - size is a multiple of 4
|
||||
|
||||
|
||||
; /*************************************************************************
|
||||
; // This part is appended after the compressed data.
|
||||
; // It runs in the last part of the dirty bss (after the relocations).
|
||||
; **************************************************************************/
|
||||
|
||||
cutpoint:
|
||||
|
||||
; ------------- decompress (from a0 to a1)
|
||||
|
||||
#if defined(NRV2B)
|
||||
# include "m68k/n2b_d.ash"
|
||||
#elif defined(NRV2D)
|
||||
# include "m68k/n2d_d.ash"
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
|
||||
|
||||
; ------------- reloc
|
||||
|
||||
; The decompressed relocations now are just after the decompressed
|
||||
; data segment, i.e. at the beginning of the (dirty) bss.
|
||||
|
||||
; note: d1 and d2 are 0 from decompressor above
|
||||
|
||||
reloc:
|
||||
;;move.w #'u3',d3 ; #0 or #1
|
||||
dc.b 'u3' ; moveq.l #0,d3 / moveq.l #1,d3
|
||||
beq reloc_end ; don't reloc
|
||||
|
||||
move.l a6,a0 ; a0 = start of relocations
|
||||
|
||||
move.l d4,a1
|
||||
add.l (a0)+,a1 ; get initial fixup
|
||||
|
||||
L(loop1): add.l d1,a1 ; increase fixup
|
||||
add.l d4,(a1) ; reloc one address
|
||||
L(loop2): move.b (a0)+,d1
|
||||
beq reloc_end
|
||||
cmp.b d3,d1 ; note: d3.b is #1
|
||||
bne L(loop1)
|
||||
lea 254(a1),a1 ; d1 == 1 -> add 254, don't reloc
|
||||
bra L(loop2)
|
||||
|
||||
reloc_end:
|
||||
|
||||
; note: d1 and d2 are still 0
|
||||
|
||||
|
||||
; ------------- clear dirty bss & start program
|
||||
|
||||
; We are currently running in the dirty bss.
|
||||
; Jump to the code we copied below the stack.
|
||||
|
||||
#if defined(SMALL)
|
||||
move.l #'up41',d0 ; dirty_bss / 4
|
||||
#else
|
||||
move.l #'up41',d0 ; dirty_bss / 16
|
||||
#endif
|
||||
|
||||
jmp (a5) ; jmp clear_bss (on stack)
|
||||
|
||||
|
||||
eof:
|
||||
dc.w cutpoint-start ; size of entry
|
||||
dc.w eof-cutpoint ; size of decompressor
|
||||
dc.b 'UPX9' ; marker for o2bin.pl
|
||||
|
||||
end
|
||||
|
||||
|
||||
; vi:ts=8:et:nowrap
|
||||
|
||||
Reference in New Issue
Block a user