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:
parent
615615b1df
commit
f86d57bfe3
@ -39,6 +39,7 @@ _start: .globl _start
|
|||||||
sz_b_info= 12
|
sz_b_info= 12
|
||||||
sz_unc= 0
|
sz_unc= 0
|
||||||
sz_cpr= 4
|
sz_cpr= 4
|
||||||
|
b_method= 8
|
||||||
|
|
||||||
PROT_READ= 1
|
PROT_READ= 1
|
||||||
PROT_WRITE= 2
|
PROT_WRITE= 2
|
||||||
@ -57,36 +58,34 @@ PAGE_SIZE = -(~0<<PAGE_SHIFT)
|
|||||||
unfold:
|
unfold:
|
||||||
mflr r30 # &{ b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...}
|
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 a5,0 # off_t
|
||||||
li a4,-1 # BSD fd
|
li a4,0 # fd; ignored, but must be in range?
|
||||||
*/
|
|
||||||
li a3,MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS
|
|
||||||
lwz a0,sz_cpr(r30)
|
lwz a0,sz_cpr(r30)
|
||||||
|
li a3,MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS
|
||||||
li a2,PROT_READ | PROT_WRITE | PROT_EXEC
|
li a2,PROT_READ | PROT_WRITE | PROT_EXEC
|
||||||
add a0,a0,r30
|
|
||||||
li a1,PAGE_SIZE
|
li a1,PAGE_SIZE
|
||||||
addi a0,a0,sz_b_info+PAGE_SIZE-1
|
add a0,a0,r30
|
||||||
li 0,SYS_mmap
|
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
|
rlwinm a0,a0,0,0,31-PAGE_SHIFT # next page boundary after fold
|
||||||
sc
|
sc
|
||||||
bso- fail # Branch if SummaryOverflow (syscall failure), unlikely
|
bns+ 0f; trap # Branch if NoSummary[Overflow] (no failure)
|
||||||
|
0:
|
||||||
mtlr a0 # &continuation
|
mtctr r31
|
||||||
|
lbz meth,b_method(r30)
|
||||||
la ldst,31*4(sp) # &do_not_care
|
la ldst,31*4(sp) # &do_not_care
|
||||||
mr dst,a0
|
mr dst,a0
|
||||||
mtctr r31
|
mtlr a0 # &continuation
|
||||||
lwz lsrc,sz_cpr(r30)
|
lwz lsrc,sz_cpr(r30)
|
||||||
addi src,r30,sz_b_info
|
addi src,r30,sz_b_info
|
||||||
bctr # goto decomrpess; return to link register (mmap'ed page)
|
bctr # goto decomrpess; return to link register (mmap'ed page)
|
||||||
fail:
|
|
||||||
trap
|
|
||||||
main:
|
main:
|
||||||
stwu r1,-32*4(sp) # allocate space (keeping 0 mod 16), save r1
|
stwu r1,-32*4(sp) # allocate space (keeping 0 mod 16), save r1
|
||||||
stmw r2,4(sp) # save registers r2 thru r31
|
stmw r2,4(sp) # save registers r2 thru r31
|
||||||
mflr r31 # &decompress
|
mflr r31 # &decompress
|
||||||
call unfold
|
call unfold
|
||||||
/* { b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...} */
|
/* { b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...} */
|
||||||
|
|
||||||
eof:
|
eof:
|
||||||
/*__XTHEENDX__*/
|
/*__XTHEENDX__*/
|
||||||
|
|||||||
@ -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.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
@ -26,11 +26,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define LINUX_ELFPPC32_LOADER_ADLER32 0x337c930d
|
#define LINUX_ELFPPC32_LOADER_ADLER32 0xd58495f3
|
||||||
#define LINUX_ELFPPC32_LOADER_CRC32 0xac495fea
|
#define LINUX_ELFPPC32_LOADER_CRC32 0x5b115466
|
||||||
|
|
||||||
unsigned char linux_elfppc32_loader[448] = {
|
unsigned char linux_elfppc32_loader[460] = {
|
||||||
72, 0, 1,177,124, 0, 41,236,144,166, 0, 0,124,132, 26, 20, /* 0x 0 */
|
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 */
|
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 */
|
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 */
|
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 */
|
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 */
|
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 */
|
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 */
|
78,128, 0, 32,127,200, 2,166, 57, 0, 0, 0, 56,224, 0, 0, /* 0x 160 */
|
||||||
56,160, 0, 7,124, 99,242, 20, 56,128, 16, 0, 56, 99, 16, 11, /* 0x 170 */
|
128,126, 0, 4, 56,192, 0, 50, 56,160, 0, 7, 56,128, 16, 0, /* 0x 170 */
|
||||||
56, 0, 0, 90, 84, 99, 0, 38, 68, 0, 0, 2, 65,131, 0, 32, /* 0x 180 */
|
124, 99,242, 20, 56, 0, 0, 90, 56, 99, 16, 11, 84, 99, 0, 38, /* 0x 180 */
|
||||||
124,104, 3,166, 56,193, 0,124,124,101, 27,120,127,233, 3,166, /* 0x 190 */
|
68, 0, 0, 2, 64,163, 0, 8,127,224, 0, 8,127,233, 3,166, /* 0x 190 */
|
||||||
128,158, 0, 4, 56,126, 0, 12, 78,128, 4, 32,127,224, 0, 8, /* 0x 1a0 */
|
136,254, 0, 8, 56,193, 0,124,124,101, 27,120,124,104, 3,166, /* 0x 1a0 */
|
||||||
148, 33,255,128,188, 65, 0, 4,127,232, 2,166, 75,255,255,169 /* 0x 1b0 */
|
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
171
src/stub/ppc_d_nrv2b.S
Normal 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
|
||||||
|
|
||||||
@ -34,7 +34,7 @@
|
|||||||
SZ_DLINE=128 # size of data cache line in Apple G5
|
SZ_DLINE=128 # size of data cache line in Apple G5
|
||||||
|
|
||||||
/* Returns 0 on success; non-zero on failure. */
|
/* 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] */
|
/* PowerPC has no 'cmplis': compare logical [unsigned] immediate shifted [by 16] */
|
||||||
#define hibit r0 /* holds 0x80000000 during decompress */
|
#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 lsrc a1
|
||||||
#define dst a2
|
#define dst a2
|
||||||
#define ldst a3 /* Out: actually a reference: &len_dst */
|
#define ldst a3 /* Out: actually a reference: &len_dst */
|
||||||
|
#define meth a4
|
||||||
|
|
||||||
#define off a4
|
#define off a4
|
||||||
#define len a5
|
#define len a5
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user