1
0
mirror of https://github.com/upx/upx synced 2025-10-05 19:20:23 +08:00

mmap() needs in-range fd; b_method as arg5 to decompress

l_lx_elfppc32.S l_lx_elfppc32.h
	ppc_d_nrv2e.S
	ppc_d_nrv2b.S

committer: jreiser <jreiser> 1109217478 +0000
This commit is contained in:
John Reiser 2005-02-24 03:57:58 +00:00
parent 615615b1df
commit f86d57bfe3
4 changed files with 198 additions and 26 deletions

View File

@ -39,6 +39,7 @@ _start: .globl _start
sz_b_info= 12
sz_unc= 0
sz_cpr= 4
b_method= 8
PROT_READ= 1
PROT_WRITE= 2
@ -57,36 +58,34 @@ PAGE_SIZE = -(~0<<PAGE_SHIFT)
unfold:
mflr r30 # &{ b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...}
/* linux ignores fd and off_t when MAP_ANONYMOUS
li a5,0 # off_t
li a4,-1 # BSD fd
*/
li a3,MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS
li a4,0 # fd; ignored, but must be in range?
lwz a0,sz_cpr(r30)
li a3,MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS
li a2,PROT_READ | PROT_WRITE | PROT_EXEC
add a0,a0,r30
li a1,PAGE_SIZE
addi a0,a0,sz_b_info+PAGE_SIZE-1
add a0,a0,r30
li 0,SYS_mmap
addi a0,a0,sz_b_info+PAGE_SIZE-1
rlwinm a0,a0,0,0,31-PAGE_SHIFT # next page boundary after fold
sc
bso- fail # Branch if SummaryOverflow (syscall failure), unlikely
mtlr a0 # &continuation
bns+ 0f; trap # Branch if NoSummary[Overflow] (no failure)
0:
mtctr r31
lbz meth,b_method(r30)
la ldst,31*4(sp) # &do_not_care
mr dst,a0
mtctr r31
mtlr a0 # &continuation
lwz lsrc,sz_cpr(r30)
addi src,r30,sz_b_info
bctr # goto decomrpess; return to link register (mmap'ed page)
fail:
trap
main:
stwu r1,-32*4(sp) # allocate space (keeping 0 mod 16), save r1
stmw r2,4(sp) # save registers r2 thru r31
mflr r31 # &decompress
mflr r31 # &decompress
call unfold
/* { b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...} */
/* { b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...} */
eof:
/*__XTHEENDX__*/

View File

@ -1,4 +1,4 @@
/* l_lx_elfppc32.h -- created from l_lx_elfppc32.bin, 448 (0x1c0) bytes
/* l_lx_elfppc32.h -- created from l_lx_elfppc32.bin, 460 (0x1cc) bytes
This file is part of the UPX executable compressor.
@ -26,11 +26,11 @@
*/
#define LINUX_ELFPPC32_LOADER_ADLER32 0x337c930d
#define LINUX_ELFPPC32_LOADER_CRC32 0xac495fea
#define LINUX_ELFPPC32_LOADER_ADLER32 0xd58495f3
#define LINUX_ELFPPC32_LOADER_CRC32 0x5b115466
unsigned char linux_elfppc32_loader[448] = {
72, 0, 1,177,124, 0, 41,236,144,166, 0, 0,124,132, 26, 20, /* 0x 0 */
unsigned char linux_elfppc32_loader[460] = {
72, 0, 1,189,124, 0, 41,236,144,166, 0, 0,124,132, 26, 20, /* 0x 0 */
60, 0,128, 0, 61, 32,128, 0, 56, 99,255,255, 56,165,255,255, /* 0x 10 */
57, 64,255,255,125,168, 2,166, 72, 0, 1, 12, 57, 32, 0, 1, /* 0x 20 */
125, 41, 28, 44, 56, 99, 0, 4,124, 9, 0, 64,125, 41, 72, 20, /* 0x 30 */
@ -52,10 +52,11 @@ unsigned char linux_elfppc32_loader[448] = {
66, 0,255,248, 56,224, 1, 0,124, 7, 41,236,124, 7, 26, 44, /* 0x 130 */
75,255,255, 16,128, 6, 0, 0,125,168, 3,166, 56,165, 0, 1, /* 0x 140 */
56, 99, 0, 1,124,160, 40, 80,124,100, 24, 80,144,166, 0, 0, /* 0x 150 */
78,128, 0, 32,127,200, 2,166, 56,192, 0, 50,128,126, 0, 4, /* 0x 160 */
56,160, 0, 7,124, 99,242, 20, 56,128, 16, 0, 56, 99, 16, 11, /* 0x 170 */
56, 0, 0, 90, 84, 99, 0, 38, 68, 0, 0, 2, 65,131, 0, 32, /* 0x 180 */
124,104, 3,166, 56,193, 0,124,124,101, 27,120,127,233, 3,166, /* 0x 190 */
128,158, 0, 4, 56,126, 0, 12, 78,128, 4, 32,127,224, 0, 8, /* 0x 1a0 */
148, 33,255,128,188, 65, 0, 4,127,232, 2,166, 75,255,255,169 /* 0x 1b0 */
78,128, 0, 32,127,200, 2,166, 57, 0, 0, 0, 56,224, 0, 0, /* 0x 160 */
128,126, 0, 4, 56,192, 0, 50, 56,160, 0, 7, 56,128, 16, 0, /* 0x 170 */
124, 99,242, 20, 56, 0, 0, 90, 56, 99, 16, 11, 84, 99, 0, 38, /* 0x 180 */
68, 0, 0, 2, 64,163, 0, 8,127,224, 0, 8,127,233, 3,166, /* 0x 190 */
136,254, 0, 8, 56,193, 0,124,124,101, 27,120,124,104, 3,166, /* 0x 1a0 */
128,158, 0, 4, 56,126, 0, 12, 78,128, 4, 32,148, 33,255,128, /* 0x 1b0 */
188, 65, 0, 4,127,232, 2,166, 75,255,255,157 /* 0x 1c0 */
};

171
src/stub/ppc_d_nrv2b.S Normal file
View File

@ -0,0 +1,171 @@
/* ppc_d_nrv2b.S -- PowerPC decompressor for NRV2B
This file is part of the UPX executable compressor.
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2004 Laszlo Molnar
Copyright (C) 2000-2005 John F. Reiser
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>
John F. Reiser
<jreiser@users.sourceforge.net>
*/
#include "ppc_regs.h"
SZ_DLINE=128 # size of data cache line in Apple G5
/* Returns 0 on success; non-zero on failure. */
decompress: # (uchar const *src, size_t lsrc, uchar *dst, size_t &ldst, uint method)
/* PowerPC has no 'cmplis': compare logical [unsigned] immediate shifted [by 16] */
#define hibit r0 /* holds 0x80000000 during decompress */
#define src a0
#define lsrc a1
#define dst a2
#define ldst a3 /* Out: actually a reference: &len_dst */
#define meth a4
#define off a4
#define len a5
#define bits a6
#define disp a7
dcbtst 0,dst # prime dcache for store
stw dst,0(ldst) # original dst
add lsrc,lsrc,src # input eof
lis hibit,0x8000 # 0x80000000 for detecting next bit
lis bits,0x8000 # prepare for first load
addi src,src,-1 # prepare for 'lbzu'
addi dst,dst,-1 # prepare for 'stbu'
li disp,-1 # initial displacement
mflr t3 # return address
b bot_n2b
/* jump on next bit, with branch prediction: y==>likely; n==>unlikely
cr0 is set by the cmpl ["compare logical"==>unsigned]:
lt next bit is 0
gt next bit is 1
eq must load next 32 bits from memory
*/
#define jnextb0y call get1; blt+ cr0,
#define jnextb0n call get1; blt- cr0,
#define jnextb1y call get1; bgt+ cr0,
#define jnextb1n call get1; bgt- cr0,
/* rotate next bit into bottom bit of reg; set cr0 based on entire result reg */
#define getnextb(reg) call get1; adde. reg,reg,reg
get1:
cmpl cr0,bits,hibit # cr0 for jnextb
addc bits,bits,bits # CArry for getnextb
bnelr+ cr0 # return if reload not needed; likely 31/32
/* CArry has been set from adding 0x80000000 to itself; preserve for 'adde' */
# fetch 4 bytes unaligned and LITTLE ENDIAN
#if 0 /*{ clean; but 4 instr larger, and 3 cycles longer */
lbz bits,1(src) # lo8
lbz t0,2(src); rlwimi bits,t0, 8,16,23
lbz t0,3(src); rlwimi bits,t0,16, 8,15
lbzu t0,4(src); rlwimi bits,t0,24, 0, 7
#else /*}{ pray for no unalignment trap or slowdown */
li bits,1 # compensate for 'lbzu'
lwbrx bits,bits,src # bits= fetch_le32(bits+src)
addi src,src,4
#endif /*}*/
cmpl cr0,bits,hibit # cr0 for jnextb
adde bits,bits,bits # CArry for getnextb; set lo bit from CarryIn
ret
lit_n2b:
#define tmp len
lbzu tmp,1(src) # tmp= *++src;
stbu tmp,1(dst) # *++dst= tmp;
#undef tmp
top_n2b:
jnextb1y lit_n2b
li off,1 # "the msb"
offmore_n2b:
getnextb(off)
jnextb0n offmore_n2b
addic. off,off,-3 # CArry set [and ignored], but no 'addi.'
li len,0
blt- offprev_n2b
lbzu t0,1(src)
rlwinm off,off,8,0,31-8 # off<<=8;
nor. disp,off,t0 # disp = -(1+ (off|t0));
beq- eof_n2b
offprev_n2b: # In: 0==len
getnextb(len); getnextb(len) # two bits; cr0 set on result
li off,1; bne- gotlen_n2b # raw 1,2,3 ==> 2,3,4
li off,3 # raw 2.. ==> 5..
li len,1 # "the msb"
lenmore_n2b:
getnextb(len)
jnextb0n lenmore_n2b
gotlen_n2b:
subfic t0,disp,(~0)+(-0xd00) # want CArry only
adde len,len,off # len += off + (disp < -0xd00);
copy:
#define back off
add back,disp,dst # point back to match in dst
mtctr len
short_n2b:
#define tmp len
lbzu tmp,1(back)
stbu tmp,1(dst)
#undef tmp
bdnz+ short_n2b
/* This "prefetch for store" is simple, small, and effective. Matches
usually occur more frequently than once per 128 bytes, but G4 line size
is only 32 bytes anyway. Assume that an 'unnecessary' dcbtst costs only
about as much as a hit. The counter register is free at top_n2b, so we could
pace the dcbtst optimally; but that takes 7 or 8 instructions of space.
*/
bot_n2b:
li back,2*SZ_DLINE
dcbtst back,dst # 2 lines ahead [-1 for stbu]
dcbt back,src # jump start auto prefetch at page boundary
/* Auto prefetch for Read quits at page boundary; needs 2 misses to restart. */
#undef back
b top_n2b
eof_n2b:
#define tmp r0 /* hibit is dead */
lwz tmp,0(ldst) # original dst
mtlr t3 # return address
addi dst,dst,1 # uncorrect for 'stbu'
addi src,src,1 # uncorrect for 'lbzu'
subf dst,tmp,dst # dst -= tmp; // dst length
#undef tmp
subf a0,lsrc,src # src -= eof; // return 0: good; else: bad
stw dst,0(ldst)
ret

View File

@ -34,7 +34,7 @@
SZ_DLINE=128 # size of data cache line in Apple G5
/* Returns 0 on success; non-zero on failure. */
decompress: # (uchar const *src, size_t lsrc, uchar *dst, size_t &ldst)
decompress: # (uchar const *src, size_t lsrc, uchar *dst, size_t &ldst, uint method)
/* PowerPC has no 'cmplis': compare logical [unsigned] immediate shifted [by 16] */
#define hibit r0 /* holds 0x80000000 during decompress */
@ -43,6 +43,7 @@ decompress: # (uchar const *src, size_t lsrc, uchar *dst, size_t &ldst)
#define lsrc a1
#define dst a2
#define ldst a3 /* Out: actually a reference: &len_dst */
#define meth a4
#define off a4
#define len a5