1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00

PPC branch+call trick: filter first 4MB only

filteri.cpp filter/ppcbxx.h stub/ppc_bxx.S

committer: jreiser <jreiser> 1114229877 +0000
This commit is contained in:
John Reiser 2005-04-23 04:17:57 +00:00
parent d339ee3135
commit c282e7fdb4
3 changed files with 21 additions and 9 deletions

View File

@ -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<<W_CTO)) & (off>>(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<<W_CTO) & (word>>(24+2 - W_CTO))) == f->cto) {
unsigned const jc = word & (~(~0u<<(26 - W_CTO)) & (~0u<<2));

View File

@ -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);

View File

@ -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<<W_CTO # cat(bxx_opcode, cto8)
movr ptr0,ptr # save base address
addi ptr,ptr,-4 # prepare for 'lwzu'