From c282e7fdb4e4571d22d8fded9bcd5d6030e9a07a Mon Sep 17 00:00:00 2001 From: John Reiser Date: Sat, 23 Apr 2005 04:17:57 +0000 Subject: [PATCH] PPC branch+call trick: filter first 4MB only filteri.cpp filter/ppcbxx.h stub/ppc_bxx.S committer: jreiser 1114229877 +0000 --- src/filter/ppcbxx.h | 11 ++++++----- src/filteri.cpp | 10 ++++++++-- src/stub/ppc_bxx.S | 9 +++++++-- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/filter/ppcbxx.h b/src/filter/ppcbxx.h index d27cdfe7..02879992 100644 --- a/src/filter/ppcbxx.h +++ b/src/filter/ppcbxx.h @@ -47,7 +47,8 @@ static int F(Filter *f) // scan const upx_byte *b = f->buf; #endif - const unsigned size = f->buf_len; + const unsigned size = umin(f->buf_len, -(~0u<<(32 - (6+ W_CTO)))); + const unsigned size4 = size -4; unsigned ic; unsigned calls = 0, noncalls = 0; @@ -62,7 +63,7 @@ static int F(Filter *f) memset(buf , 0, WW); memset(buf + WW, 1, 256 - WW); - for (ic = 0; ic < size - 4; ic+=4) if (COND(b,ic)) { + for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) { unsigned const off = (int)(get_be32(b+ic)<<6) >>6; if (size <= (off & (~0u<<2))+ic) { buf[(~(~0u<>(26 - W_CTO))] |= 1; @@ -81,7 +82,7 @@ static int F(Filter *f) const unsigned cto = (unsigned)f->cto << (24+2 - W_CTO); #endif - for (ic = 0; ic < size - 4; ic+=4) if (COND(b,ic)) { + for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) { unsigned const word = get_be32(b+ic); unsigned const off = (int)(word<<6) >>6; unsigned const jc = (off & (~0u<<2))+ic; @@ -121,12 +122,12 @@ static int F(Filter *f) static int U(Filter *f) { upx_byte *b = f->buf; - const unsigned size4 = f->buf_len - 4; + const unsigned size4 = umin(f->buf_len - 4, -(~0u<<(32 - (6+ W_CTO)))); const unsigned addvalue = f->addvalue; unsigned ic; - for (ic = 0; ic < size4; ic+=4) if (COND(b,ic)) { + for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) { unsigned const word = get_be32(b+ic); if ((~(~0u<>(24+2 - W_CTO))) == f->cto) { unsigned const jc = word & (~(~0u<<(26 - W_CTO)) & (~0u<<2)); diff --git a/src/filteri.cpp b/src/filteri.cpp index c98c4e75..10d19ff3 100644 --- a/src/filteri.cpp +++ b/src/filteri.cpp @@ -29,6 +29,12 @@ #include "conf.h" #include "filter.h" +static unsigned +umin(unsigned const a, unsigned const b) +{ + return (a<=b) ? a : b; +} + #define set_dummy(p, v) ((void)0) #define get_8(p) (*(p)) @@ -244,8 +250,8 @@ const FilterImp::FilterEntry FilterImp::filters[] = { { 0xb2,99, 0, f_sub32_3, u_sub32_3, s_sub32_3 }, { 0xb3,99, 0, f_sub32_4, u_sub32_4, s_sub32_4 }, - // PowerPC call trick - { 0xd0, 8, 0x01000000, f_ppcbxx, u_ppcbxx, s_ppcbxx }, + // PowerPC branch+call trick + { 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx }, }; const int FilterImp::n_filters = TABLESIZE(filters); diff --git a/src/stub/ppc_bxx.S b/src/stub/ppc_bxx.S index 15dd395d..f24523ee 100644 --- a/src/stub/ppc_bxx.S +++ b/src/stub/ppc_bxx.S @@ -36,8 +36,13 @@ ppcbxx: # (*f_unf)(xo->buf, out_len, h.b_cto8, h.b_ftid); #define ptr0 a4 - cmpli cr0,ftid,0xd0; bnelr- cr0 # if (0xd0!=ftid) return; - rlwinm. len,len,32-2,2,31; beqlr- cr0 # if (0==(len>>=2)) return; + cmpli cr0,ftid,0xd0; bnelr- cr0 # if (0xd0!=ftid) return; + rlwinm. len,len,32-2,2,31; beqlr- cr0 # if (0==(len>>=2)) return; + lis r0,-(~0<<(32-16- (2+6+ W_CTO))) # limit in 32-bit words + cmpl cr0,len,r0 + blt cr0,L5 + mr len,r0 +L5: addi cto8,cto8,18<