1
/* ppcbxx.h -- PowerPC Branch trick
3
This file is part of the UPX executable compressor.
5
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
6
Copyright (C) 1996-2004 Laszlo Molnar
7
Copyright (C) 2004-2005 John F. Reiser
10
UPX and the UCL library are free software; you can redistribute them
11
and/or modify them under the terms of the GNU General Public License as
12
published by the Free Software Foundation; either version 2 of
13
the License, or (at your option) any later version.
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with this program; see the file COPYING.
22
If not, write to the Free Software Foundation, Inc.,
23
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
Markus F.X.J. Oberhumer Laszlo Molnar
26
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
29
<jreiser@users.sourceforge.net>
34
/*************************************************************************
36
**************************************************************************/
38
#define W_CTO 4 /* width of cto; must match stub/ppc_bxx.S */
40
static int F(Filter *f)
45
const unsigned addvalue = f->addvalue;
48
const upx_byte *b = f->buf;
50
const unsigned size = umin(f->buf_len, -(~0u<<(32 - (6+ W_CTO))));
51
const unsigned size4 = size -4;
54
unsigned calls = 0, noncalls = 0;
55
unsigned lastnoncall = size, lastcall = 0;
57
// find 26-2-W_CTO bits of displacements that contain no targets
59
unsigned char buf[256];
60
unsigned short wbuf[256];
61
const size_t WW = (size_t)0 - (~(size_t)0) << W_CTO; // ???
62
memset(wbuf, 0, sizeof(wbuf));
64
memset(buf + WW, 1, 256 - WW);
66
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) {
67
unsigned const off = (int)(get_be32(b+ic)<<6) >>6;
68
if (size <= (off & (~0u<<2))+ic) {
69
buf[(~(~0u<<W_CTO)) & (off>>(26 - W_CTO))] |= 1;
70
++wbuf[0xff&(off>>18)];
74
if (getcto(f, buf) < 0) {
75
if (0!=W_CTO) // FIXME: what is this ???
80
const unsigned char cto8 = f->cto;
82
const unsigned cto = (unsigned)f->cto << (24+2 - W_CTO);
85
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) {
86
unsigned const word = get_be32(b+ic);
87
unsigned const off = (int)(word<<6) >>6;
88
unsigned const jc = (off & (~0u<<2))+ic;
89
// try to detect 'real' calls only
92
set_be32(b+ic,(0xfc000003&word) | (jc+addvalue+cto));
98
assert(0==W_CTO // FIXME: what is this ???
99
|| (~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) != cto8); // this should not happen
106
f->noncalls = noncalls;
107
f->lastcall = lastcall;
110
printf("\ncalls=%d noncalls=%d text_size=%x calltrickoffset=%x\n",
111
calls,noncalls,size,cto8);
117
/*************************************************************************
119
**************************************************************************/
122
static int U(Filter *f)
124
upx_byte *b = f->buf;
125
const unsigned size4 = umin(f->buf_len - 4, -(~0u<<(32 - (6+ W_CTO))));
126
const unsigned addvalue = f->addvalue;
130
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) {
131
unsigned const word = get_be32(b+ic);
132
if ((~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) == f->cto) {
133
unsigned const jc = word & (~(~0u<<(26 - W_CTO)) & (~0u<<2));
134
set_be32(b+ic, (0xfc000003&word)|(0x03fffffc&(jc-ic-addvalue)));