Upx_Doxygen
https://github.com/upx/upx
bele.h
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-2016 Markus Franz Xaver Johannes Oberhumer
6  Copyright (C) 1996-2016 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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
145 inline unsigned get_le32(const void *p)
146 {
147 #if defined(ACC_UA_GET_LE32)
148  return ACC_UA_GET_LE32(p);
149 #else
150  return acc_ua_get_le32(p);
151 #endif
152 }
153 
154 inline void set_le32(void *p, unsigned v)
155 {
156 #if defined(ACC_UA_SET_LE32)
157  ACC_UA_SET_LE32(p, v);
158 #else
159  acc_ua_set_le32(p, v);
160 #endif
161 }
162 
163 inline upx_uint64_t get_le64(const void *p)
164 {
165 #if defined(ACC_UA_GET_LE64)
166  return ACC_UA_GET_LE64(p);
167 #else
168  return acc_ua_get_le64(p);
169 #endif
170 }
171 
172 inline void set_le64(void *p, upx_uint64_t v)
173 {
174 #if defined(ACC_UA_SET_LE64)
175  ACC_UA_SET_LE64(p, v);
176 #else
177  acc_ua_set_le64(p, v);
178 #endif
179 }
180 
181 
182 /*************************************************************************
183 // get signed values, i.e. sign-extend
184 **************************************************************************/
185 
186 inline int sign_extend(unsigned v, unsigned bits)
187 {
188  const unsigned sign_bit = 1u << (bits - 1);
189  v &= sign_bit | (sign_bit - 1);
190  v |= 0 - (v & sign_bit);
191  return ACC_ICAST(int, v);
192 }
193 
194 inline upx_int64_t sign_extend(upx_uint64_t v, unsigned bits)
195 {
196  const upx_uint64_t sign_bit = UPX_UINT64_C(1) << (bits - 1);
197  v &= sign_bit | (sign_bit - 1);
198  v |= 0 - (v & sign_bit);
199  return ACC_ICAST(upx_int64_t, v);
200 }
201 
202 inline int get_be16_signed(const void *p)
203 {
204  unsigned v = get_be16(p);
205  return sign_extend(v, 16);
206 }
207 
208 inline int get_be24_signed(const void *p)
209 {
210  unsigned v = get_be24(p);
211  return sign_extend(v, 24);
212 }
213 
214 inline int get_be32_signed(const void *p)
215 {
216  unsigned v = get_be32(p);
217  return sign_extend(v, 32);
218 }
219 
220 inline upx_int64_t get_be64_signed(const void *p)
221 {
222  upx_uint64_t v = get_be64(p);
223  return sign_extend(v, 64);
224 }
225 
226 inline int get_le16_signed(const void *p)
227 {
228  unsigned v = get_le16(p);
229  return sign_extend(v, 16);
230 }
231 
232 inline int get_le24_signed(const void *p)
233 {
234  unsigned v = get_le24(p);
235  return sign_extend(v, 24);
236 }
237 
238 inline int get_le32_signed(const void *p)
239 {
240  unsigned v = get_le32(p);
241  return sign_extend(v, 32);
242 }
243 
244 inline upx_int64_t get_le64_signed(const void *p)
245 {
246  upx_uint64_t v = get_le64(p);
247  return sign_extend(v, 64);
248 }
249 
250 
251 /*************************************************************************
252 // swab (bswap)
253 **************************************************************************/
254 
255 inline unsigned acc_swab16(unsigned v)
256 {
257  return ((v & 0x00ff) << 8) |
258  ((v & 0xff00) >> 8);
259 }
260 
261 inline unsigned acc_swab32(unsigned v)
262 {
263  return ((v & 0x000000ff) << 24) |
264  ((v & 0x0000ff00) << 8) |
265  ((v & 0x00ff0000) >> 8) |
266  ((v & 0xff000000) >> 24);
267 }
268 
269 
270 inline unsigned acc_swab16p(const upx_uint16_t *p)
271 {
272  return acc_swab16(*p);
273 }
274 
275 inline unsigned acc_swap32p(const upx_uint32_t *p)
276 {
277  return acc_swab32(*p);
278 }
279 
280 
281 inline void acc_swab16s(upx_uint16_t *p)
282 {
283  *p = ACC_ICONV(upx_uint16_t, acc_swab16(*p));
284 }
285 
286 inline void acc_swab32s(upx_uint32_t *p)
287 {
288  *p = ACC_ICONV(upx_uint32_t, acc_swab32(*p));
289 }
290 
291 
292 inline void acc_ua_swab16s(void *p)
293 {
294  set_be16(p, get_le16(p));
295 }
296 
297 inline void acc_ua_swab32s(void *p)
298 {
299  set_be32(p, get_le32(p));
300 }
301 
302 
303 /*************************************************************************
304 // classes for portable unaligned access
305 //
306 // Important: these classes must be PODs (Plain Old Data), i.e. no
307 // constructor, no destructor, no virtual functions and no default
308 // assignment operator, and all fields must be public(!).
309 //
310 // [Actually we _can_ use a safe non-POD subset, but for this we need
311 // to have gcc bug 17519 fixed - see http://gcc.gnu.org/PR17519 ]
312 **************************************************************************/
313 
314 __packed_struct(BE16)
315  unsigned char d[2];
316 
317  BE16& operator = (unsigned v) { set_be16(d, v); return *this; }
318  BE16& operator += (unsigned v) { set_be16(d, get_be16(d) + v); return *this; }
319  BE16& operator -= (unsigned v) { set_be16(d, get_be16(d) - v); return *this; }
320  BE16& operator *= (unsigned v) { set_be16(d, get_be16(d) * v); return *this; }
321  BE16& operator /= (unsigned v) { set_be16(d, get_be16(d) / v); return *this; }
322  BE16& operator &= (unsigned v) { set_be16(d, get_be16(d) & v); return *this; }
323  BE16& operator |= (unsigned v) { set_be16(d, get_be16(d) | v); return *this; }
324  BE16& operator ^= (unsigned v) { set_be16(d, get_be16(d) ^ v); return *this; }
325  BE16& operator <<= (unsigned v) { set_be16(d, get_be16(d) << v); return *this; }
326  BE16& operator >>= (unsigned v) { set_be16(d, get_be16(d) >> v); return *this; }
327 
328  operator unsigned () const { return get_be16(d); }
329 __packed_struct_end()
330 
331 
332 __packed_struct(BE32)
333  unsigned char d[4];
334 
335  BE32& operator = (unsigned v) { set_be32(d, v); return *this; }
336  BE32& operator += (unsigned v) { set_be32(d, get_be32(d) + v); return *this; }
337  BE32& operator -= (unsigned v) { set_be32(d, get_be32(d) - v); return *this; }
338  BE32& operator *= (unsigned v) { set_be32(d, get_be32(d) * v); return *this; }
339  BE32& operator /= (unsigned v) { set_be32(d, get_be32(d) / v); return *this; }
340  BE32& operator &= (unsigned v) { set_be32(d, get_be32(d) & v); return *this; }
341  BE32& operator |= (unsigned v) { set_be32(d, get_be32(d) | v); return *this; }
342  BE32& operator ^= (unsigned v) { set_be32(d, get_be32(d) ^ v); return *this; }
343  BE32& operator <<= (unsigned v) { set_be32(d, get_be32(d) << v); return *this; }
344  BE32& operator >>= (unsigned v) { set_be32(d, get_be32(d) >> v); return *this; }
345 
346  operator unsigned () const { return get_be32(d); }
347 __packed_struct_end()
348 
349 
350 __packed_struct(BE64)
351  unsigned char d[8];
352 
353  BE64& operator = (upx_uint64_t v) { set_be64(d, v); return *this; }
354  BE64& operator += (upx_uint64_t v) { set_be64(d, get_be64(d) + v); return *this; }
355  BE64& operator -= (upx_uint64_t v) { set_be64(d, get_be64(d) - v); return *this; }
356  BE64& operator *= (upx_uint64_t v) { set_be64(d, get_be64(d) * v); return *this; }
357  BE64& operator /= (upx_uint64_t v) { set_be64(d, get_be64(d) / v); return *this; }
358  BE64& operator &= (upx_uint64_t v) { set_be64(d, get_be64(d) & v); return *this; }
359  BE64& operator |= (upx_uint64_t v) { set_be64(d, get_be64(d) | v); return *this; }
360  BE64& operator ^= (upx_uint64_t v) { set_be64(d, get_be64(d) ^ v); return *this; }
361  BE64& operator <<= (unsigned v) { set_be64(d, get_be64(d) << v); return *this; }
362  BE64& operator >>= (unsigned v) { set_be64(d, get_be64(d) >> v); return *this; }
363 
364  operator upx_uint64_t () const { return get_be64(d); }
365 __packed_struct_end()
366 
367 
368 __packed_struct(LE16)
369  unsigned char d[2];
370 
371  LE16& operator = (unsigned v) { set_le16(d, v); return *this; }
372  LE16& operator += (unsigned v) { set_le16(d, get_le16(d) + v); return *this; }
373  LE16& operator -= (unsigned v) { set_le16(d, get_le16(d) - v); return *this; }
374  LE16& operator *= (unsigned v) { set_le16(d, get_le16(d) * v); return *this; }
375  LE16& operator /= (unsigned v) { set_le16(d, get_le16(d) / v); return *this; }
376  LE16& operator &= (unsigned v) { set_le16(d, get_le16(d) & v); return *this; }
377  LE16& operator |= (unsigned v) { set_le16(d, get_le16(d) | v); return *this; }
378  LE16& operator ^= (unsigned v) { set_le16(d, get_le16(d) ^ v); return *this; }
379  LE16& operator <<= (unsigned v) { set_le16(d, get_le16(d) << v); return *this; }
380  LE16& operator >>= (unsigned v) { set_le16(d, get_le16(d) >> v); return *this; }
381 
382  operator unsigned () const { return get_le16(d); }
383 __packed_struct_end()
384 
385 
386 __packed_struct(LE32)
387  unsigned char d[4];
388 
389  LE32& operator = (unsigned v) { set_le32(d, v); return *this; }
390  LE32& operator += (unsigned v) { set_le32(d, get_le32(d) + v); return *this; }
391  LE32& operator -= (unsigned v) { set_le32(d, get_le32(d) - v); return *this; }
392  LE32& operator *= (unsigned v) { set_le32(d, get_le32(d) * v); return *this; }
393  LE32& operator /= (unsigned v) { set_le32(d, get_le32(d) / v); return *this; }
394  LE32& operator &= (unsigned v) { set_le32(d, get_le32(d) & v); return *this; }
395  LE32& operator |= (unsigned v) { set_le32(d, get_le32(d) | v); return *this; }
396  LE32& operator ^= (unsigned v) { set_le32(d, get_le32(d) ^ v); return *this; }
397  LE32& operator <<= (unsigned v) { set_le32(d, get_le32(d) << v); return *this; }
398  LE32& operator >>= (unsigned v) { set_le32(d, get_le32(d) >> v); return *this; }
399 
400  operator unsigned () const { return get_le32(d); }
401 __packed_struct_end()
402 
403 
404 __packed_struct(LE64)
405  unsigned char d[8];
406 
407  LE64& operator = (upx_uint64_t v) { set_le64(d, v); return *this; }
408  LE64& operator += (upx_uint64_t v) { set_le64(d, get_le64(d) + v); return *this; }
409  LE64& operator -= (upx_uint64_t v) { set_le64(d, get_le64(d) - v); return *this; }
410  LE64& operator *= (upx_uint64_t v) { set_le64(d, get_le64(d) * v); return *this; }
411  LE64& operator /= (upx_uint64_t v) { set_le64(d, get_le64(d) / v); return *this; }
412  LE64& operator &= (upx_uint64_t v) { set_le64(d, get_le64(d) & v); return *this; }
413  LE64& operator |= (upx_uint64_t v) { set_le64(d, get_le64(d) | v); return *this; }
414  LE64& operator ^= (upx_uint64_t v) { set_le64(d, get_le64(d) ^ v); return *this; }
415  LE64& operator <<= (unsigned v) { set_le64(d, get_le64(d) << v); return *this; }
416  LE64& operator >>= (unsigned v) { set_le64(d, get_le64(d) >> v); return *this; }
417 
418  operator upx_uint64_t () const { return get_le64(d); }
419 __packed_struct_end()
420 
421 
422 /*************************************************************************
423 // global operators
424 **************************************************************************/
425 
426 template <class T>
427 inline T* operator + (T* ptr, const BE16& v) { return ptr + (unsigned) v; }
428 template <class T>
429 inline T* operator + (const BE16& v, T* ptr) { return ptr + (unsigned) v; }
430 template <class T>
431 inline T* operator - (T* ptr, const BE16& v) { return ptr - (unsigned) v; }
432 
433 template <class T>
434 inline T* operator + (T* ptr, const BE32& v) { return ptr + (unsigned) v; }
435 template <class T>
436 inline T* operator + (const BE32& v, T* ptr) { return ptr + (unsigned) v; }
437 template <class T>
438 inline T* operator - (T* ptr, const BE32& v) { return ptr - (unsigned) v; }
439 
440 // these are not implemented on purpose and will cause link-time errors
441 template <class T> T* operator + (T* ptr, const BE64& v);
442 template <class T> T* operator + (const BE64& v, T* ptr);
443 template <class T> T* operator - (T* ptr, const BE64& v);
444 
445 template <class T>
446 inline T* operator + (T* ptr, const LE16& v) { return ptr + (unsigned) v; }
447 template <class T>
448 inline T* operator + (const LE16& v, T* ptr) { return ptr + (unsigned) v; }
449 template <class T>
450 inline T* operator - (T* ptr, const LE16& v) { return ptr - (unsigned) v; }
451 
452 template <class T>
453 inline T* operator + (T* ptr, const LE32& v) { return ptr + (unsigned) v; }
454 template <class T>
455 inline T* operator + (const LE32& v, T* ptr) { return ptr + (unsigned) v; }
456 template <class T>
457 inline T* operator - (T* ptr, const LE32& v) { return ptr - (unsigned) v; }
458 
459 // these are not implemented on purpose and will cause link-time errors
460 template <class T> T* operator + (T* ptr, const LE64& v);
461 template <class T> T* operator + (const LE64& v, T* ptr);
462 template <class T> T* operator - (T* ptr, const LE64& v);
463 
464 
465 /*************************************************************************
466 // global overloads
467 **************************************************************************/
468 
469 inline unsigned ALIGN_DOWN(unsigned a, const BE32& b) { return ALIGN_DOWN(a, (unsigned) b); }
470 inline unsigned ALIGN_DOWN(const BE32& a, unsigned b) { return ALIGN_DOWN((unsigned) a, b); }
471 inline unsigned ALIGN_UP (unsigned a, const BE32& b) { return ALIGN_UP (a, (unsigned) b); }
472 inline unsigned ALIGN_UP (const BE32& a, unsigned b) { return ALIGN_UP ((unsigned) a, b); }
473 
474 inline unsigned ALIGN_DOWN(unsigned a, const LE32& b) { return ALIGN_DOWN(a, (unsigned) b); }
475 inline unsigned ALIGN_DOWN(const LE32& a, unsigned b) { return ALIGN_DOWN((unsigned) a, b); }
476 inline unsigned ALIGN_UP (unsigned a, const LE32& b) { return ALIGN_UP (a, (unsigned) b); }
477 inline unsigned ALIGN_UP (const LE32& a, unsigned b) { return ALIGN_UP ((unsigned) a, b); }
478 
479 inline unsigned UPX_MAX(unsigned a, const BE16& b) { return UPX_MAX(a, (unsigned) b); }
480 inline unsigned UPX_MAX(const BE16& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
481 inline unsigned UPX_MIN(unsigned a, const BE16& b) { return UPX_MIN(a, (unsigned) b); }
482 inline unsigned UPX_MIN(const BE16& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
483 
484 inline unsigned UPX_MAX(unsigned a, const BE32& b) { return UPX_MAX(a, (unsigned) b); }
485 inline unsigned UPX_MAX(const BE32& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
486 inline unsigned UPX_MIN(unsigned a, const BE32& b) { return UPX_MIN(a, (unsigned) b); }
487 inline unsigned UPX_MIN(const BE32& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
488 
489 inline unsigned UPX_MAX(unsigned a, const LE16& b) { return UPX_MAX(a, (unsigned) b); }
490 inline unsigned UPX_MAX(const LE16& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
491 inline unsigned UPX_MIN(unsigned a, const LE16& b) { return UPX_MIN(a, (unsigned) b); }
492 inline unsigned UPX_MIN(const LE16& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
493 
494 inline unsigned UPX_MAX(unsigned a, const LE32& b) { return UPX_MAX(a, (unsigned) b); }
495 inline unsigned UPX_MAX(const LE32& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
496 inline unsigned UPX_MIN(unsigned a, const LE32& b) { return UPX_MIN(a, (unsigned) b); }
497 inline unsigned UPX_MIN(const LE32& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
498 
499 
500 /*************************************************************************
501 // misc
502 **************************************************************************/
503 
504 // for use with qsort()
505 extern "C" {
506 int __acc_cdecl_qsort be16_compare(const void *, const void *);
507 int __acc_cdecl_qsort be24_compare(const void *, const void *);
508 int __acc_cdecl_qsort be32_compare(const void *, const void *);
509 int __acc_cdecl_qsort be64_compare(const void *, const void *);
510 int __acc_cdecl_qsort le16_compare(const void *, const void *);
511 int __acc_cdecl_qsort le24_compare(const void *, const void *);
512 int __acc_cdecl_qsort le32_compare(const void *, const void *);
513 int __acc_cdecl_qsort le64_compare(const void *, const void *);
514 int __acc_cdecl_qsort be16_compare_signed(const void *, const void *);
515 int __acc_cdecl_qsort be24_compare_signed(const void *, const void *);
516 int __acc_cdecl_qsort be32_compare_signed(const void *, const void *);
517 int __acc_cdecl_qsort be64_compare_signed(const void *, const void *);
518 int __acc_cdecl_qsort le16_compare_signed(const void *, const void *);
519 int __acc_cdecl_qsort le24_compare_signed(const void *, const void *);
520 int __acc_cdecl_qsort le32_compare_signed(const void *, const void *);
521 int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
522 } // extern "C"
523 
524 
525 /*************************************************************************
526 // Provide namespaces and classes to abstract endianness policies.
527 //
528 // CTP - Compile-Time Polymorphism (templates)
529 // RTP - Run-Time Polymorphism (virtual functions)
530 **************************************************************************/
531 
532 // forward declarations
533 namespace N_BELE_CTP {
534 struct BEPolicy;
535 struct LEPolicy;
536 extern const BEPolicy be_policy;
537 extern const LEPolicy le_policy;
538 }
539 namespace N_BELE_RTP {
540 struct AbstractPolicy;
541 struct BEPolicy;
542 struct LEPolicy;
543 extern const BEPolicy be_policy;
544 extern const LEPolicy le_policy;
545 }
546 
547 namespace N_BELE_CTP {
548 #define BELE_CTP 1
549 #include "bele_policy.h"
550 #undef BELE_CTP
551 }
552 
553 namespace N_BELE_RTP {
554 #define BELE_RTP 1
555 #include "bele_policy.h"
556 #undef BELE_RTP
557 }
558 
559 namespace N_BELE_CTP {
560 inline const N_BELE_RTP::AbstractPolicy* getRTP(const BEPolicy*)
561  { return &N_BELE_RTP::be_policy; }
562 inline const N_BELE_RTP::AbstractPolicy* getRTP(const LEPolicy*)
563  { return &N_BELE_RTP::le_policy; }
564 }
565 
566 
567 #endif /* already included */
568 
569 /* vim:set ts=4 sw=4 et: */
Definition: bele.h:533
Definition: bele.h:539
Definition: bele.h:170
Definition: bele.h:93
Definition: bele.h:55