1 /* bele.h -- access memory in BigEndian and LittleEndian byte order
2 
3    This file is part of the UPX executable compressor.
4 
5    Copyright (C) 1996-2020 Markus Franz Xaver Johannes Oberhumer
6    Copyright (C) 1996-2020 Laszlo Molnar
7    All Rights Reserved.
8 
9    UPX and the UCL library are free software; you can redistribute them
10    and/or modify them under the terms of the GNU General Public License as
11    published by the Free Software Foundation; either version 2 of
12    the License, or (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; see the file COPYING.
21    If not, write to the Free Software Foundation, Inc.,
22    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 
24    Markus F.X.J. Oberhumer              Laszlo Molnar
25    <markus@oberhumer.com>               <ezerotven+github@gmail.com>
26  */
27 
28 
29 #ifndef __UPX_BELE_H
30 #define __UPX_BELE_H 1
31 
32 
33 /*************************************************************************
34 // core
35 **************************************************************************/
36 
get_be16(const void * p)37 inline unsigned get_be16(const void *p)
38 {
39 #if defined(ACC_UA_GET_BE16)
40     return ACC_UA_GET_BE16(p);
41 #else
42     return acc_ua_get_be16(p);
43 #endif
44 }
45 
set_be16(void * p,unsigned v)46 inline void set_be16(void *p, unsigned v)
47 {
48 #if defined(ACC_UA_SET_BE16)
49     ACC_UA_SET_BE16(p, v);
50 #else
51     acc_ua_set_be16(p, v);
52 #endif
53 }
54 
get_be24(const void * p)55 inline unsigned get_be24(const void *p)
56 {
57 #if defined(ACC_UA_GET_BE24)
58     return ACC_UA_GET_BE24(p);
59 #else
60     return acc_ua_get_be24(p);
61 #endif
62 }
63 
set_be24(void * p,unsigned v)64 inline void set_be24(void *p, unsigned v)
65 {
66 #if defined(ACC_UA_SET_BE24)
67     ACC_UA_SET_BE24(p, v);
68 #else
69     acc_ua_set_be24(p, v);
70 #endif
71 }
72 
get_be32(const void * p)73 inline unsigned get_be32(const void *p)
74 {
75 #if defined(ACC_UA_GET_BE32)
76     return ACC_UA_GET_BE32(p);
77 #else
78     return acc_ua_get_be32(p);
79 #endif
80 }
81 
set_be32(void * p,unsigned v)82 inline void set_be32(void *p, unsigned v)
83 {
84 #if defined(ACC_UA_SET_BE32)
85     ACC_UA_SET_BE32(p, v);
86 #else
87     acc_ua_set_be32(p, v);
88 #endif
89 }
90 
get_be64(const void * p)91 inline upx_uint64_t get_be64(const void *p)
92 {
93 #if defined(ACC_UA_GET_BE64)
94     return ACC_UA_GET_BE64(p);
95 #else
96     return acc_ua_get_be64(p);
97 #endif
98 }
99 
set_be64(void * p,upx_uint64_t v)100 inline void set_be64(void *p, upx_uint64_t v)
101 {
102 #if defined(ACC_UA_SET_BE64)
103     ACC_UA_SET_BE64(p, v);
104 #else
105     acc_ua_set_be64(p, v);
106 #endif
107 }
108 
get_le16(const void * p)109 inline unsigned get_le16(const void *p)
110 {
111 #if defined(ACC_UA_GET_LE16)
112     return ACC_UA_GET_LE16(p);
113 #else
114     return acc_ua_get_le16(p);
115 #endif
116 }
117 
set_le16(void * p,unsigned v)118 inline void set_le16(void *p, unsigned v)
119 {
120 #if defined(ACC_UA_SET_LE16)
121     ACC_UA_SET_LE16(p, v);
122 #else
123     acc_ua_set_le16(p, v);
124 #endif
125 }
126 
get_le24(const void * p)127 inline unsigned get_le24(const void *p)
128 {
129 #if defined(ACC_UA_GET_LE24)
130     return ACC_UA_GET_LE24(p);
131 #else
132     return acc_ua_get_le24(p);
133 #endif
134 }
135 
set_le24(void * p,unsigned v)136 inline void set_le24(void *p, unsigned v)
137 {
138 #if defined(ACC_UA_SET_LE24)
139     ACC_UA_SET_LE24(p, v);
140 #else
141     acc_ua_set_le24(p, v);
142 #endif
143 }
144 
get_le26(const void * p)145 inline unsigned get_le26(const void *p)
146 {
147     const acc_hbyte_p b = ACC_CCAST(const acc_hbyte_p, p);
148     return ACC_ICONV(acc_uint32l_t, b[0]       ) | (  ACC_ICONV(acc_uint32l_t, b[1])     <<  8) |
149           (ACC_ICONV(acc_uint32l_t, b[2]) << 16) | (((ACC_ICONV(acc_uint32l_t, b[3]) & 3)<< 24));
150 }
151 
set_le26(void * p,unsigned v)152 inline void set_le26(void *p, unsigned v)
153 {
154     acc_hbyte_p b = ACC_PCAST(acc_hbyte_p, p);
155     b[0] = ACC_ICONV(unsigned char, (v >>  0) & 0xff);
156     b[1] = ACC_ICONV(unsigned char, (v >>  8) & 0xff);
157     b[2] = ACC_ICONV(unsigned char, (v >> 16) & 0xff);
158     b[3] = ACC_ICONV(unsigned char, (v >> 24) & 0x03) | (0xFC & b[3]);
159 }
160 
get_le32(const void * p)161 inline unsigned get_le32(const void *p)
162 {
163 #if defined(ACC_UA_GET_LE32)
164     return ACC_UA_GET_LE32(p);
165 #else
166     return acc_ua_get_le32(p);
167 #endif
168 }
169 
set_le32(void * p,unsigned v)170 inline void set_le32(void *p, unsigned v)
171 {
172 #if defined(ACC_UA_SET_LE32)
173     ACC_UA_SET_LE32(p, v);
174 #else
175     acc_ua_set_le32(p, v);
176 #endif
177 }
178 
get_le64(const void * p)179 inline upx_uint64_t get_le64(const void *p)
180 {
181 #if defined(ACC_UA_GET_LE64)
182     return ACC_UA_GET_LE64(p);
183 #else
184     return acc_ua_get_le64(p);
185 #endif
186 }
187 
set_le64(void * p,upx_uint64_t v)188 inline void set_le64(void *p, upx_uint64_t v)
189 {
190 #if defined(ACC_UA_SET_LE64)
191     ACC_UA_SET_LE64(p, v);
192 #else
193     acc_ua_set_le64(p, v);
194 #endif
195 }
196 
197 
198 /*************************************************************************
199 // get signed values, i.e. sign-extend
200 **************************************************************************/
201 
sign_extend(unsigned v,unsigned bits)202 inline int sign_extend(unsigned v, unsigned bits)
203 {
204     const unsigned sign_bit = 1u << (bits - 1);
205     v &= sign_bit | (sign_bit - 1);
206     v |= 0 - (v & sign_bit);
207     return ACC_ICAST(int, v);
208 }
209 
sign_extend(upx_uint64_t v,unsigned bits)210 inline upx_int64_t sign_extend(upx_uint64_t v, unsigned bits)
211 {
212     const upx_uint64_t sign_bit = UPX_UINT64_C(1) << (bits - 1);
213     v &= sign_bit | (sign_bit - 1);
214     v |= 0 - (v & sign_bit);
215     return ACC_ICAST(upx_int64_t, v);
216 }
217 
get_be16_signed(const void * p)218 inline int get_be16_signed(const void *p)
219 {
220     unsigned v = get_be16(p);
221     return sign_extend(v, 16);
222 }
223 
get_be24_signed(const void * p)224 inline int get_be24_signed(const void *p)
225 {
226     unsigned v = get_be24(p);
227     return sign_extend(v, 24);
228 }
229 
get_be32_signed(const void * p)230 inline int get_be32_signed(const void *p)
231 {
232     unsigned v = get_be32(p);
233     return sign_extend(v, 32);
234 }
235 
get_be64_signed(const void * p)236 inline upx_int64_t get_be64_signed(const void *p)
237 {
238     upx_uint64_t v = get_be64(p);
239     return sign_extend(v, 64);
240 }
241 
get_le16_signed(const void * p)242 inline int get_le16_signed(const void *p)
243 {
244     unsigned v = get_le16(p);
245     return sign_extend(v, 16);
246 }
247 
get_le24_signed(const void * p)248 inline int get_le24_signed(const void *p)
249 {
250     unsigned v = get_le24(p);
251     return sign_extend(v, 24);
252 }
253 
get_le32_signed(const void * p)254 inline int get_le32_signed(const void *p)
255 {
256     unsigned v = get_le32(p);
257     return sign_extend(v, 32);
258 }
259 
get_le64_signed(const void * p)260 inline upx_int64_t get_le64_signed(const void *p)
261 {
262     upx_uint64_t v = get_le64(p);
263     return sign_extend(v, 64);
264 }
265 
266 
267 /*************************************************************************
268 // swab (bswap)
269 **************************************************************************/
270 
acc_swab16(unsigned v)271 inline unsigned acc_swab16(unsigned v)
272 {
273     return ((v & 0x00ff) << 8) |
274            ((v & 0xff00) >> 8);
275 }
276 
acc_swab32(unsigned v)277 inline unsigned acc_swab32(unsigned v)
278 {
279     return ((v & 0x000000ff) << 24) |
280            ((v & 0x0000ff00) <<  8) |
281            ((v & 0x00ff0000) >>  8) |
282            ((v & 0xff000000) >> 24);
283 }
284 
285 
acc_swab16p(const upx_uint16_t * p)286 inline unsigned acc_swab16p(const upx_uint16_t *p)
287 {
288     return acc_swab16(*p);
289 }
290 
acc_swap32p(const upx_uint32_t * p)291 inline unsigned acc_swap32p(const upx_uint32_t *p)
292 {
293     return acc_swab32(*p);
294 }
295 
296 
acc_swab16s(upx_uint16_t * p)297 inline void acc_swab16s(upx_uint16_t *p)
298 {
299     *p = ACC_ICONV(upx_uint16_t, acc_swab16(*p));
300 }
301 
acc_swab32s(upx_uint32_t * p)302 inline void acc_swab32s(upx_uint32_t *p)
303 {
304     *p = ACC_ICONV(upx_uint32_t, acc_swab32(*p));
305 }
306 
307 
acc_ua_swab16s(void * p)308 inline void acc_ua_swab16s(void *p)
309 {
310     set_be16(p, get_le16(p));
311 }
312 
acc_ua_swab32s(void * p)313 inline void acc_ua_swab32s(void *p)
314 {
315     set_be32(p, get_le32(p));
316 }
317 
318 
319 /*************************************************************************
320 // classes for portable unaligned access
321 //
322 // Important: these classes must be PODs (Plain Old Data), i.e. no
323 //   constructor, no destructor, no virtual functions and no default
324 //   assignment operator, and all fields must be public(!).
325 //
326 // [Actually we _can_ use a safe non-POD subset, but for this we need
327 //  to have gcc bug 17519 fixed - see http://gcc.gnu.org/PR17519 ]
328 **************************************************************************/
329 
__packed_struct(BE16)330 __packed_struct(BE16)
331     unsigned char d[2];
332 
333     BE16& operator =  (unsigned v) { set_be16(d, v); return *this; }
334     BE16& operator += (unsigned v) { set_be16(d, get_be16(d) + v); return *this; }
335     BE16& operator -= (unsigned v) { set_be16(d, get_be16(d) - v); return *this; }
336     BE16& operator *= (unsigned v) { set_be16(d, get_be16(d) * v); return *this; }
337     BE16& operator /= (unsigned v) { set_be16(d, get_be16(d) / v); return *this; }
338     BE16& operator &= (unsigned v) { set_be16(d, get_be16(d) & v); return *this; }
339     BE16& operator |= (unsigned v) { set_be16(d, get_be16(d) | v); return *this; }
340     BE16& operator ^= (unsigned v) { set_be16(d, get_be16(d) ^ v); return *this; }
341     BE16& operator <<= (unsigned v) { set_be16(d, get_be16(d) << v); return *this; }
342     BE16& operator >>= (unsigned v) { set_be16(d, get_be16(d) >> v); return *this; }
343 
344     operator unsigned () const { return get_be16(d); }
345 __packed_struct_end()
346 
347 
348 __packed_struct(BE32)
349     unsigned char d[4];
350 
351     BE32& operator =  (unsigned v) { set_be32(d, v); return *this; }
352     BE32& operator += (unsigned v) { set_be32(d, get_be32(d) + v); return *this; }
353     BE32& operator -= (unsigned v) { set_be32(d, get_be32(d) - v); return *this; }
354     BE32& operator *= (unsigned v) { set_be32(d, get_be32(d) * v); return *this; }
355     BE32& operator /= (unsigned v) { set_be32(d, get_be32(d) / v); return *this; }
356     BE32& operator &= (unsigned v) { set_be32(d, get_be32(d) & v); return *this; }
357     BE32& operator |= (unsigned v) { set_be32(d, get_be32(d) | v); return *this; }
358     BE32& operator ^= (unsigned v) { set_be32(d, get_be32(d) ^ v); return *this; }
359     BE32& operator <<= (unsigned v) { set_be32(d, get_be32(d) << v); return *this; }
360     BE32& operator >>= (unsigned v) { set_be32(d, get_be32(d) >> v); return *this; }
361 
362     operator unsigned () const { return get_be32(d); }
363 __packed_struct_end()
364 
365 
366 __packed_struct(BE64)
367     unsigned char d[8];
368 
369     BE64& operator =  (upx_uint64_t v) { set_be64(d, v); return *this; }
370     BE64& operator += (upx_uint64_t v) { set_be64(d, get_be64(d) + v); return *this; }
371     BE64& operator -= (upx_uint64_t v) { set_be64(d, get_be64(d) - v); return *this; }
372     BE64& operator *= (upx_uint64_t v) { set_be64(d, get_be64(d) * v); return *this; }
373     BE64& operator /= (upx_uint64_t v) { set_be64(d, get_be64(d) / v); return *this; }
374     BE64& operator &= (upx_uint64_t v) { set_be64(d, get_be64(d) & v); return *this; }
375     BE64& operator |= (upx_uint64_t v) { set_be64(d, get_be64(d) | v); return *this; }
376     BE64& operator ^= (upx_uint64_t v) { set_be64(d, get_be64(d) ^ v); return *this; }
377     BE64& operator <<= (unsigned v) { set_be64(d, get_be64(d) << v); return *this; }
378     BE64& operator >>= (unsigned v) { set_be64(d, get_be64(d) >> v); return *this; }
379 
upx_uint64_t()380     operator upx_uint64_t () const { return get_be64(d); }
381 __packed_struct_end()
382 
383 
384 __packed_struct(LE16)
385     unsigned char d[2];
386 
387     LE16& operator =  (unsigned v) { set_le16(d, v); return *this; }
388     LE16& operator += (unsigned v) { set_le16(d, get_le16(d) + v); return *this; }
389     LE16& operator -= (unsigned v) { set_le16(d, get_le16(d) - v); return *this; }
390     LE16& operator *= (unsigned v) { set_le16(d, get_le16(d) * v); return *this; }
391     LE16& operator /= (unsigned v) { set_le16(d, get_le16(d) / v); return *this; }
392     LE16& operator &= (unsigned v) { set_le16(d, get_le16(d) & v); return *this; }
393     LE16& operator |= (unsigned v) { set_le16(d, get_le16(d) | v); return *this; }
394     LE16& operator ^= (unsigned v) { set_le16(d, get_le16(d) ^ v); return *this; }
395     LE16& operator <<= (unsigned v) { set_le16(d, get_le16(d) << v); return *this; }
396     LE16& operator >>= (unsigned v) { set_le16(d, get_le16(d) >> v); return *this; }
397 
398     operator unsigned () const { return get_le16(d); }
399 __packed_struct_end()
400 
401 
402 __packed_struct(LE32)
403     unsigned char d[4];
404 
405     LE32& operator =  (unsigned v) { set_le32(d, v); return *this; }
406     LE32& operator += (unsigned v) { set_le32(d, get_le32(d) + v); return *this; }
407     LE32& operator -= (unsigned v) { set_le32(d, get_le32(d) - v); return *this; }
408     LE32& operator *= (unsigned v) { set_le32(d, get_le32(d) * v); return *this; }
409     LE32& operator /= (unsigned v) { set_le32(d, get_le32(d) / v); return *this; }
410     LE32& operator &= (unsigned v) { set_le32(d, get_le32(d) & v); return *this; }
411     LE32& operator |= (unsigned v) { set_le32(d, get_le32(d) | v); return *this; }
412     LE32& operator ^= (unsigned v) { set_le32(d, get_le32(d) ^ v); return *this; }
413     LE32& operator <<= (unsigned v) { set_le32(d, get_le32(d) << v); return *this; }
414     LE32& operator >>= (unsigned v) { set_le32(d, get_le32(d) >> v); return *this; }
415 
416     operator unsigned () const { return get_le32(d); }
417 __packed_struct_end()
418 
419 
420 __packed_struct(LE64)
421     unsigned char d[8];
422 
423     LE64& operator =  (upx_uint64_t v) { set_le64(d, v); return *this; }
424     LE64& operator += (upx_uint64_t v) { set_le64(d, get_le64(d) + v); return *this; }
425     LE64& operator -= (upx_uint64_t v) { set_le64(d, get_le64(d) - v); return *this; }
426     LE64& operator *= (upx_uint64_t v) { set_le64(d, get_le64(d) * v); return *this; }
427     LE64& operator /= (upx_uint64_t v) { set_le64(d, get_le64(d) / v); return *this; }
428     LE64& operator &= (upx_uint64_t v) { set_le64(d, get_le64(d) & v); return *this; }
429     LE64& operator |= (upx_uint64_t v) { set_le64(d, get_le64(d) | v); return *this; }
430     LE64& operator ^= (upx_uint64_t v) { set_le64(d, get_le64(d) ^ v); return *this; }
431     LE64& operator <<= (unsigned v) { set_le64(d, get_le64(d) << v); return *this; }
432     LE64& operator >>= (unsigned v) { set_le64(d, get_le64(d) >> v); return *this; }
433 
upx_uint64_t()434     operator upx_uint64_t () const { return get_le64(d); }
435 __packed_struct_end()
436 
437 
438 /*************************************************************************
439 // global operators
440 **************************************************************************/
441 
442 template <class T>
443 inline T* operator + (T* ptr, const BE16& v) { return ptr + (unsigned) v; }
444 template <class T>
445 inline T* operator + (const BE16& v, T* ptr) { return ptr + (unsigned) v; }
446 template <class T>
447 inline T* operator - (T* ptr, const BE16& v) { return ptr - (unsigned) v; }
448 
449 template <class T>
450 inline T* operator + (T* ptr, const BE32& v) { return ptr + (unsigned) v; }
451 template <class T>
452 inline T* operator + (const BE32& v, T* ptr) { return ptr + (unsigned) v; }
453 template <class T>
454 inline T* operator - (T* ptr, const BE32& v) { return ptr - (unsigned) v; }
455 
456 // these are not implemented on purpose and will cause link-time errors
457 template <class T> T* operator + (T* ptr, const BE64& v);
458 template <class T> T* operator + (const BE64& v, T* ptr);
459 template <class T> T* operator - (T* ptr, const BE64& v);
460 
461 template <class T>
462 inline T* operator + (T* ptr, const LE16& v) { return ptr + (unsigned) v; }
463 template <class T>
464 inline T* operator + (const LE16& v, T* ptr) { return ptr + (unsigned) v; }
465 template <class T>
466 inline T* operator - (T* ptr, const LE16& v) { return ptr - (unsigned) v; }
467 
468 template <class T>
469 inline T* operator + (T* ptr, const LE32& v) { return ptr + (unsigned) v; }
470 template <class T>
471 inline T* operator + (const LE32& v, T* ptr) { return ptr + (unsigned) v; }
472 template <class T>
473 inline T* operator - (T* ptr, const LE32& v) { return ptr - (unsigned) v; }
474 
475 // these are not implemented on purpose and will cause link-time errors
476 template <class T> T* operator + (T* ptr, const LE64& v);
477 template <class T> T* operator + (const LE64& v, T* ptr);
478 template <class T> T* operator - (T* ptr, const LE64& v);
479 
480 
481 /*************************************************************************
482 // global overloads
483 **************************************************************************/
484 
ALIGN_DOWN(unsigned a,const BE32 & b)485 inline unsigned ALIGN_DOWN(unsigned a, const BE32& b) { return ALIGN_DOWN(a, (unsigned) b); }
ALIGN_DOWN(const BE32 & a,unsigned b)486 inline unsigned ALIGN_DOWN(const BE32& a, unsigned b) { return ALIGN_DOWN((unsigned) a, b); }
ALIGN_UP(unsigned a,const BE32 & b)487 inline unsigned ALIGN_UP  (unsigned a, const BE32& b) { return ALIGN_UP  (a, (unsigned) b); }
ALIGN_UP(const BE32 & a,unsigned b)488 inline unsigned ALIGN_UP  (const BE32& a, unsigned b) { return ALIGN_UP  ((unsigned) a, b); }
489 
ALIGN_DOWN(unsigned a,const LE32 & b)490 inline unsigned ALIGN_DOWN(unsigned a, const LE32& b) { return ALIGN_DOWN(a, (unsigned) b); }
ALIGN_DOWN(const LE32 & a,unsigned b)491 inline unsigned ALIGN_DOWN(const LE32& a, unsigned b) { return ALIGN_DOWN((unsigned) a, b); }
ALIGN_UP(unsigned a,const LE32 & b)492 inline unsigned ALIGN_UP  (unsigned a, const LE32& b) { return ALIGN_UP  (a, (unsigned) b); }
ALIGN_UP(const LE32 & a,unsigned b)493 inline unsigned ALIGN_UP  (const LE32& a, unsigned b) { return ALIGN_UP  ((unsigned) a, b); }
494 
UPX_MAX(unsigned a,const BE16 & b)495 inline unsigned UPX_MAX(unsigned a, const BE16& b)    { return UPX_MAX(a, (unsigned) b); }
UPX_MAX(const BE16 & a,unsigned b)496 inline unsigned UPX_MAX(const BE16& a, unsigned b)    { return UPX_MAX((unsigned) a, b); }
UPX_MIN(unsigned a,const BE16 & b)497 inline unsigned UPX_MIN(unsigned a, const BE16& b)    { return UPX_MIN(a, (unsigned) b); }
UPX_MIN(const BE16 & a,unsigned b)498 inline unsigned UPX_MIN(const BE16& a, unsigned b)    { return UPX_MIN((unsigned) a, b); }
499 
UPX_MAX(unsigned a,const BE32 & b)500 inline unsigned UPX_MAX(unsigned a, const BE32& b)    { return UPX_MAX(a, (unsigned) b); }
UPX_MAX(const BE32 & a,unsigned b)501 inline unsigned UPX_MAX(const BE32& a, unsigned b)    { return UPX_MAX((unsigned) a, b); }
UPX_MIN(unsigned a,const BE32 & b)502 inline unsigned UPX_MIN(unsigned a, const BE32& b)    { return UPX_MIN(a, (unsigned) b); }
UPX_MIN(const BE32 & a,unsigned b)503 inline unsigned UPX_MIN(const BE32& a, unsigned b)    { return UPX_MIN((unsigned) a, b); }
504 
UPX_MAX(unsigned a,const LE16 & b)505 inline unsigned UPX_MAX(unsigned a, const LE16& b)    { return UPX_MAX(a, (unsigned) b); }
UPX_MAX(const LE16 & a,unsigned b)506 inline unsigned UPX_MAX(const LE16& a, unsigned b)    { return UPX_MAX((unsigned) a, b); }
UPX_MIN(unsigned a,const LE16 & b)507 inline unsigned UPX_MIN(unsigned a, const LE16& b)    { return UPX_MIN(a, (unsigned) b); }
UPX_MIN(const LE16 & a,unsigned b)508 inline unsigned UPX_MIN(const LE16& a, unsigned b)    { return UPX_MIN((unsigned) a, b); }
509 
UPX_MAX(unsigned a,const LE32 & b)510 inline unsigned UPX_MAX(unsigned a, const LE32& b)    { return UPX_MAX(a, (unsigned) b); }
UPX_MAX(const LE32 & a,unsigned b)511 inline unsigned UPX_MAX(const LE32& a, unsigned b)    { return UPX_MAX((unsigned) a, b); }
UPX_MIN(unsigned a,const LE32 & b)512 inline unsigned UPX_MIN(unsigned a, const LE32& b)    { return UPX_MIN(a, (unsigned) b); }
UPX_MIN(const LE32 & a,unsigned b)513 inline unsigned UPX_MIN(const LE32& a, unsigned b)    { return UPX_MIN((unsigned) a, b); }
514 
515 
516 /*************************************************************************
517 // misc
518 **************************************************************************/
519 
520 // for use with qsort()
521 extern "C" {
522 int __acc_cdecl_qsort be16_compare(const void *, const void *);
523 int __acc_cdecl_qsort be24_compare(const void *, const void *);
524 int __acc_cdecl_qsort be32_compare(const void *, const void *);
525 int __acc_cdecl_qsort be64_compare(const void *, const void *);
526 int __acc_cdecl_qsort le16_compare(const void *, const void *);
527 int __acc_cdecl_qsort le24_compare(const void *, const void *);
528 int __acc_cdecl_qsort le32_compare(const void *, const void *);
529 int __acc_cdecl_qsort le64_compare(const void *, const void *);
530 int __acc_cdecl_qsort be16_compare_signed(const void *, const void *);
531 int __acc_cdecl_qsort be24_compare_signed(const void *, const void *);
532 int __acc_cdecl_qsort be32_compare_signed(const void *, const void *);
533 int __acc_cdecl_qsort be64_compare_signed(const void *, const void *);
534 int __acc_cdecl_qsort le16_compare_signed(const void *, const void *);
535 int __acc_cdecl_qsort le24_compare_signed(const void *, const void *);
536 int __acc_cdecl_qsort le32_compare_signed(const void *, const void *);
537 int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
538 } // extern "C"
539 
540 
541 /*************************************************************************
542 // Provide namespaces and classes to abstract endianness policies.
543 //
544 // CTP - Compile-Time Polymorphism (templates)
545 // RTP - Run-Time Polymorphism (virtual functions)
546 **************************************************************************/
547 
548 // forward declarations
549 namespace N_BELE_CTP {
550 struct BEPolicy;
551 struct LEPolicy;
552 extern const BEPolicy be_policy;
553 extern const LEPolicy le_policy;
554 }
555 namespace N_BELE_RTP {
556 struct AbstractPolicy;
557 struct BEPolicy;
558 struct LEPolicy;
559 extern const BEPolicy be_policy;
560 extern const LEPolicy le_policy;
561 }
562 
563 namespace N_BELE_CTP {
564 #define BELE_CTP 1
565 #include "bele_policy.h"
566 #undef BELE_CTP
567 }
568 
569 namespace N_BELE_RTP {
570 #define BELE_RTP 1
571 #include "bele_policy.h"
572 #undef BELE_RTP
573 }
574 
575 namespace N_BELE_CTP {
getRTP(const BEPolicy *)576 inline const N_BELE_RTP::AbstractPolicy* getRTP(const BEPolicy*)
577     { return &N_BELE_RTP::be_policy; }
getRTP(const LEPolicy *)578 inline const N_BELE_RTP::AbstractPolicy* getRTP(const LEPolicy*)
579     { return &N_BELE_RTP::le_policy; }
580 }
581 
582 
583 #endif /* already included */
584 
585 /* vim:set ts=4 sw=4 et: */
586