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:
parent
d339ee3135
commit
c282e7fdb4
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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'
|
||||
|
|
Loading…
Reference in New Issue
Block a user