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:
+6
-5
@@ -47,7 +47,8 @@ static int F(Filter *f)
|
|||||||
// scan
|
// scan
|
||||||
const upx_byte *b = f->buf;
|
const upx_byte *b = f->buf;
|
||||||
#endif
|
#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 ic;
|
||||||
unsigned calls = 0, noncalls = 0;
|
unsigned calls = 0, noncalls = 0;
|
||||||
@@ -62,7 +63,7 @@ static int F(Filter *f)
|
|||||||
memset(buf , 0, WW);
|
memset(buf , 0, WW);
|
||||||
memset(buf + WW, 1, 256 - 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;
|
unsigned const off = (int)(get_be32(b+ic)<<6) >>6;
|
||||||
if (size <= (off & (~0u<<2))+ic) {
|
if (size <= (off & (~0u<<2))+ic) {
|
||||||
buf[(~(~0u<<W_CTO)) & (off>>(26 - W_CTO))] |= 1;
|
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);
|
const unsigned cto = (unsigned)f->cto << (24+2 - W_CTO);
|
||||||
#endif
|
#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 word = get_be32(b+ic);
|
||||||
unsigned const off = (int)(word<<6) >>6;
|
unsigned const off = (int)(word<<6) >>6;
|
||||||
unsigned const jc = (off & (~0u<<2))+ic;
|
unsigned const jc = (off & (~0u<<2))+ic;
|
||||||
@@ -121,12 +122,12 @@ static int F(Filter *f)
|
|||||||
static int U(Filter *f)
|
static int U(Filter *f)
|
||||||
{
|
{
|
||||||
upx_byte *b = f->buf;
|
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;
|
const unsigned addvalue = f->addvalue;
|
||||||
|
|
||||||
unsigned ic;
|
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);
|
unsigned const word = get_be32(b+ic);
|
||||||
if ((~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) == f->cto) {
|
if ((~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) == f->cto) {
|
||||||
unsigned const jc = word & (~(~0u<<(26 - W_CTO)) & (~0u<<2));
|
unsigned const jc = word & (~(~0u<<(26 - W_CTO)) & (~0u<<2));
|
||||||
|
|||||||
+8
-2
@@ -29,6 +29,12 @@
|
|||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "filter.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 set_dummy(p, v) ((void)0)
|
||||||
#define get_8(p) (*(p))
|
#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 },
|
{ 0xb2,99, 0, f_sub32_3, u_sub32_3, s_sub32_3 },
|
||||||
{ 0xb3,99, 0, f_sub32_4, u_sub32_4, s_sub32_4 },
|
{ 0xb3,99, 0, f_sub32_4, u_sub32_4, s_sub32_4 },
|
||||||
|
|
||||||
// PowerPC call trick
|
// PowerPC branch+call trick
|
||||||
{ 0xd0, 8, 0x01000000, f_ppcbxx, u_ppcbxx, s_ppcbxx },
|
{ 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx },
|
||||||
};
|
};
|
||||||
|
|
||||||
const int FilterImp::n_filters = TABLESIZE(filters);
|
const int FilterImp::n_filters = TABLESIZE(filters);
|
||||||
|
|||||||
@@ -38,6 +38,11 @@ ppcbxx: # (*f_unf)(xo->buf, out_len, h.b_cto8, h.b_ftid);
|
|||||||
|
|
||||||
cmpli cr0,ftid,0xd0; bnelr- cr0 # if (0xd0!=ftid) 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;
|
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)
|
addi cto8,cto8,18<<W_CTO # cat(bxx_opcode, cto8)
|
||||||
movr ptr0,ptr # save base address
|
movr ptr0,ptr # save base address
|
||||||
addi ptr,ptr,-4 # prepare for 'lwzu'
|
addi ptr,ptr,-4 # prepare for 'lwzu'
|
||||||
|
|||||||
Reference in New Issue
Block a user