Coverage Report

Created: 2025-07-12 06:52

/src/upx/src/bele.h
Line
Count
Source (jump to first uncovered line)
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-2025 Markus Franz Xaver Johannes Oberhumer
6
   Copyright (C) 1996-2025 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
#pragma once
29
30
// BE - Big Endian
31
// LE - Little Endian
32
// NE - Native Endianness (aka Host Endianness aka CPU Endianness)
33
// TE - Target Endianness (not used here, see various packers)
34
35
static_assert(std::is_same_v<byte, unsigned char>);
36
static_assert(std::is_same_v<upx_int32_t, int>);
37
static_assert(std::is_same_v<upx_uint32_t, unsigned>);
38
39
#if defined(upx_is_constant_evaluated)
40
#define bele_constexpr constexpr
41
#else
42
#define bele_constexpr /*empty*/
43
#endif
44
45
// forward declarations
46
struct BE16;
47
struct BE32;
48
struct BE64;
49
struct LE16;
50
struct LE32;
51
struct LE64;
52
53
/*************************************************************************
54
// XE - eXtended Endian compatibility
55
// try to detect XX16 vs XX32 vs XX64 size mismatches
56
**************************************************************************/
57
58
#if !defined(upx_is_constant_evaluated) && !(DEBUG)
59
60
// permissive version using "void *"
61
#define REQUIRE_XE16 /*empty*/
62
#define REQUIRE_XE24 /*empty*/
63
#define REQUIRE_XE32 /*empty*/
64
#define REQUIRE_XE64 /*empty*/
65
typedef void XE16;
66
typedef void XE24;
67
typedef void XE32;
68
typedef void XE64;
69
70
#else // permissive version
71
72
namespace bele_detail {
73
74
// Note:
75
//   void is explicitly allowed (but there is no automatic pointer conversion because of template!)
76
//   char is explicitly allowed
77
//   byte is explicitly allowed
78
template <class T>
79
inline constexpr bool is_xe16_type =
80
    upx::is_same_any_v<T, void, char, byte, upx_int16_t, upx_uint16_t, BE16, LE16>;
81
template <class T>
82
inline constexpr bool is_xe24_type = upx::is_same_any_v<T, void, char, byte>;
83
template <class T>
84
inline constexpr bool is_xe32_type =
85
    upx::is_same_any_v<T, void, char, byte, upx_int32_t, upx_uint32_t, BE32, LE32>;
86
template <class T>
87
inline constexpr bool is_xe64_type =
88
    upx::is_same_any_v<T, void, char, byte, upx_int64_t, upx_uint64_t, BE64, LE64>;
89
90
template <class T>
91
using enable_if_xe16 = std::enable_if_t<is_xe16_type<T>, T>;
92
template <class T>
93
using enable_if_xe24 = std::enable_if_t<is_xe24_type<T>, T>;
94
template <class T>
95
using enable_if_xe32 = std::enable_if_t<is_xe32_type<T>, T>;
96
template <class T>
97
using enable_if_xe64 = std::enable_if_t<is_xe64_type<T>, T>;
98
99
} // namespace bele_detail
100
101
#define REQUIRE_XE16 template <class XE16, class = bele_detail::enable_if_xe16<XE16> >
102
#define REQUIRE_XE24 template <class XE24, class = bele_detail::enable_if_xe24<XE24> >
103
#define REQUIRE_XE32 template <class XE32, class = bele_detail::enable_if_xe32<XE32> >
104
#define REQUIRE_XE64 template <class XE64, class = bele_detail::enable_if_xe64<XE64> >
105
106
#endif // permissive version
107
108
/*************************************************************************
109
// core - NE
110
**************************************************************************/
111
112
10.2M
forceinline bele_constexpr unsigned get_ne16(const byte *p) noexcept {
113
10.2M
#if defined(upx_is_constant_evaluated)
114
10.2M
    if (upx_is_constant_evaluated())
115
0
        return upx::compile_time::get_ne16(p);
116
10.2M
    else
117
10.2M
#endif
118
10.2M
    {
119
10.2M
        upx_uint16_t v = 0;
120
10.2M
        upx_memcpy_inline(&v, p, sizeof(v));
121
10.2M
        return v;
122
10.2M
    }
123
10.2M
}
124
125
16.1M
forceinline bele_constexpr unsigned get_ne32(const byte *p) noexcept {
126
16.1M
#if defined(upx_is_constant_evaluated)
127
16.1M
    if (upx_is_constant_evaluated())
128
0
        return upx::compile_time::get_ne32(p);
129
16.1M
    else
130
16.1M
#endif
131
16.1M
    {
132
16.1M
        upx_uint32_t v = 0;
133
16.1M
        upx_memcpy_inline(&v, p, sizeof(v));
134
16.1M
        return v;
135
16.1M
    }
136
16.1M
}
137
138
9.89M
forceinline bele_constexpr upx_uint64_t get_ne64(const byte *p) noexcept {
139
9.89M
#if defined(upx_is_constant_evaluated)
140
9.89M
    if (upx_is_constant_evaluated())
141
0
        return upx::compile_time::get_ne64(p);
142
9.89M
    else
143
9.89M
#endif
144
9.89M
    {
145
9.89M
        upx_uint64_t v = 0;
146
9.89M
        upx_memcpy_inline(&v, p, sizeof(v));
147
9.89M
        return v;
148
9.89M
    }
149
9.89M
}
150
151
1.90M
forceinline bele_constexpr void set_ne16(byte *p, unsigned v) noexcept {
152
1.90M
#if defined(upx_is_constant_evaluated)
153
1.90M
    if (upx_is_constant_evaluated())
154
0
        upx::compile_time::set_ne16(p, upx_uint16_t(v & 0xffff));
155
1.90M
    else
156
1.90M
#endif
157
1.90M
    {
158
1.90M
        upx_uint16_t vv = upx_uint16_t(v & 0xffff);
159
1.90M
        upx_memcpy_inline(p, &vv, sizeof(vv));
160
1.90M
    }
161
1.90M
}
162
163
4.46M
forceinline bele_constexpr void set_ne32(byte *p, unsigned v) noexcept {
164
4.46M
#if defined(upx_is_constant_evaluated)
165
4.46M
    if (upx_is_constant_evaluated())
166
0
        upx::compile_time::set_ne32(p, v);
167
4.46M
    else
168
4.46M
#endif
169
4.46M
    {
170
4.46M
        upx_uint32_t vv = v;
171
4.46M
        upx_memcpy_inline(p, &vv, sizeof(vv));
172
4.46M
    }
173
4.46M
}
174
175
1.71M
forceinline bele_constexpr void set_ne64(byte *p, upx_uint64_t v) noexcept {
176
1.71M
#if defined(upx_is_constant_evaluated)
177
1.71M
    if (upx_is_constant_evaluated())
178
0
        upx::compile_time::set_ne64(p, v);
179
1.71M
    else
180
1.71M
#endif
181
1.71M
    {
182
1.71M
        upx_uint64_t vv = v;
183
1.71M
        upx_memcpy_inline(p, &vv, sizeof(vv));
184
1.71M
    }
185
1.71M
}
186
187
/*************************************************************************
188
// core - NE
189
**************************************************************************/
190
191
REQUIRE_XE16
192
411k
forceinline bele_constexpr unsigned get_ne16(const XE16 *p) noexcept {
193
411k
    return get_ne16(upx::ptr_static_cast<const byte *>(p));
194
411k
}
unsigned int get_ne16<void, void>(void const*)
Line
Count
Source
192
365k
forceinline bele_constexpr unsigned get_ne16(const XE16 *p) noexcept {
193
365k
    return get_ne16(upx::ptr_static_cast<const byte *>(p));
194
365k
}
unsigned int get_ne16<unsigned short, unsigned short>(unsigned short const*)
Line
Count
Source
192
15.6k
forceinline bele_constexpr unsigned get_ne16(const XE16 *p) noexcept {
193
15.6k
    return get_ne16(upx::ptr_static_cast<const byte *>(p));
194
15.6k
}
unsigned int get_ne16<LE16, LE16>(LE16 const*)
Line
Count
Source
192
30.0k
forceinline bele_constexpr unsigned get_ne16(const XE16 *p) noexcept {
193
30.0k
    return get_ne16(upx::ptr_static_cast<const byte *>(p));
194
30.0k
}
195
196
REQUIRE_XE32
197
1.20M
forceinline bele_constexpr unsigned get_ne32(const XE32 *p) noexcept {
198
1.20M
    return get_ne32(upx::ptr_static_cast<const byte *>(p));
199
1.20M
}
unsigned int get_ne32<void, void>(void const*)
Line
Count
Source
197
1.18M
forceinline bele_constexpr unsigned get_ne32(const XE32 *p) noexcept {
198
1.18M
    return get_ne32(upx::ptr_static_cast<const byte *>(p));
199
1.18M
}
unsigned int get_ne32<unsigned int, unsigned int>(unsigned int const*)
Line
Count
Source
197
15.6k
forceinline bele_constexpr unsigned get_ne32(const XE32 *p) noexcept {
198
15.6k
    return get_ne32(upx::ptr_static_cast<const byte *>(p));
199
15.6k
}
unsigned int get_ne32<LE32, LE32>(LE32 const*)
Line
Count
Source
197
1.05k
forceinline bele_constexpr unsigned get_ne32(const XE32 *p) noexcept {
198
1.05k
    return get_ne32(upx::ptr_static_cast<const byte *>(p));
199
1.05k
}
Unexecuted instantiation: unsigned int get_ne32<char, char>(char const*)
200
201
REQUIRE_XE64
202
228k
forceinline bele_constexpr upx_uint64_t get_ne64(const XE64 *p) noexcept {
203
228k
    return get_ne64(upx::ptr_static_cast<const byte *>(p));
204
228k
}
unsigned long long get_ne64<void, void>(void const*)
Line
Count
Source
202
213k
forceinline bele_constexpr upx_uint64_t get_ne64(const XE64 *p) noexcept {
203
213k
    return get_ne64(upx::ptr_static_cast<const byte *>(p));
204
213k
}
unsigned long long get_ne64<unsigned long long, unsigned long long>(unsigned long long const*)
Line
Count
Source
202
15.6k
forceinline bele_constexpr upx_uint64_t get_ne64(const XE64 *p) noexcept {
203
15.6k
    return get_ne64(upx::ptr_static_cast<const byte *>(p));
204
15.6k
}
205
206
REQUIRE_XE16
207
15.6k
forceinline bele_constexpr void set_ne16(XE16 *p, unsigned v) noexcept {
208
15.6k
    set_ne16(upx::ptr_static_cast<byte *>(p), v);
209
15.6k
}
Unexecuted instantiation: void set_ne16<void, void>(void*, unsigned int)
void set_ne16<unsigned short, unsigned short>(unsigned short*, unsigned int)
Line
Count
Source
207
15.6k
forceinline bele_constexpr void set_ne16(XE16 *p, unsigned v) noexcept {
208
15.6k
    set_ne16(upx::ptr_static_cast<byte *>(p), v);
209
15.6k
}
Unexecuted instantiation: void set_ne16<LE16, LE16>(LE16*, unsigned int)
210
211
REQUIRE_XE32
212
46.9k
forceinline bele_constexpr void set_ne32(XE32 *p, unsigned v) noexcept {
213
46.9k
    set_ne32(upx::ptr_static_cast<byte *>(p), v);
214
46.9k
}
void set_ne32<void, void>(void*, unsigned int)
Line
Count
Source
212
31.3k
forceinline bele_constexpr void set_ne32(XE32 *p, unsigned v) noexcept {
213
31.3k
    set_ne32(upx::ptr_static_cast<byte *>(p), v);
214
31.3k
}
void set_ne32<unsigned int, unsigned int>(unsigned int*, unsigned int)
Line
Count
Source
212
15.6k
forceinline bele_constexpr void set_ne32(XE32 *p, unsigned v) noexcept {
213
15.6k
    set_ne32(upx::ptr_static_cast<byte *>(p), v);
214
15.6k
}
Unexecuted instantiation: void set_ne32<LE32, LE32>(LE32*, unsigned int)
Unexecuted instantiation: void set_ne32<char, char>(char*, unsigned int)
215
216
REQUIRE_XE64
217
15.6k
forceinline bele_constexpr void set_ne64(XE64 *p, upx_uint64_t v) noexcept {
218
15.6k
    set_ne64(upx::ptr_static_cast<byte *>(p), v);
219
15.6k
}
Unexecuted instantiation: void set_ne64<void, void>(void*, unsigned long long)
void set_ne64<unsigned long long, unsigned long long>(unsigned long long*, unsigned long long)
Line
Count
Source
217
15.6k
forceinline bele_constexpr void set_ne64(XE64 *p, upx_uint64_t v) noexcept {
218
15.6k
    set_ne64(upx::ptr_static_cast<byte *>(p), v);
219
15.6k
}
220
221
/*************************************************************************
222
// core - bswap
223
**************************************************************************/
224
225
#if __cpp_lib_byteswap >= 202110L
226
227
forceinline constexpr unsigned bswap16(unsigned v) noexcept {
228
    return std::byteswap(upx_uint16_t(v & 0xffff));
229
}
230
forceinline constexpr unsigned bswap32(unsigned v) noexcept { return std::byteswap(v); }
231
forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) noexcept { return std::byteswap(v); }
232
233
#elif (ACC_CC_MSC)
234
235
static_assert(sizeof(long) == 4);
236
237
// _byteswap_XXX is unfortunately *not* constexpr with current MSVC
238
forceinline bele_constexpr unsigned bswap16(unsigned v) noexcept {
239
#if defined(upx_is_constant_evaluated)
240
    if (upx_is_constant_evaluated())
241
        return upx::compile_time::bswap16(upx_uint16_t(v & 0xffff));
242
    else
243
#endif
244
        return (unsigned) _byteswap_ulong(v << 16);
245
}
246
forceinline bele_constexpr unsigned bswap32(unsigned v) noexcept {
247
#if defined(upx_is_constant_evaluated)
248
    if (upx_is_constant_evaluated())
249
        return upx::compile_time::bswap32(v);
250
    else
251
#endif
252
        return (unsigned) _byteswap_ulong(v);
253
}
254
forceinline bele_constexpr upx_uint64_t bswap64(upx_uint64_t v) noexcept {
255
#if defined(upx_is_constant_evaluated)
256
    if (upx_is_constant_evaluated())
257
        return upx::compile_time::bswap64(v);
258
    else
259
#endif
260
        return _byteswap_uint64(v);
261
}
262
263
#else
264
265
5.74M
forceinline constexpr unsigned bswap16(unsigned v) noexcept {
266
#if defined(__riscv) && __riscv_xlen == 64
267
    return (unsigned) __builtin_bswap64(upx_uint64_t(v) << 48);
268
#else
269
    // return __builtin_bswap16(upx_uint16_t(v & 0xffff));
270
5.74M
    return __builtin_bswap32(v << 16);
271
5.74M
#endif
272
5.74M
}
273
9.12M
forceinline constexpr unsigned bswap32(unsigned v) noexcept {
274
#if defined(__riscv) && __riscv_xlen == 64
275
    return (unsigned) __builtin_bswap64(upx_uint64_t(v) << 32);
276
#else
277
9.12M
    return __builtin_bswap32(v);
278
9.12M
#endif
279
9.12M
}
280
5.70M
forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) noexcept { return __builtin_bswap64(v); }
281
282
#endif
283
284
6.41M
forceinline constexpr unsigned no_bswap16(unsigned v) noexcept {
285
    // mask is needed so that for all v: bswap16(bswap16(v)) == no_bswap16(v)
286
6.41M
    return v & 0xffff;
287
6.41M
}
288
10.7M
forceinline constexpr unsigned no_bswap32(unsigned v) noexcept { return v; }
289
5.87M
forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) noexcept { return v; }
290
291
#if (ACC_ABI_BIG_ENDIAN)
292
#define ne16_to_be16(v) no_bswap16(v)
293
#define ne32_to_be32(v) no_bswap32(v)
294
#define ne64_to_be64(v) no_bswap64(v)
295
#define ne16_to_le16(v) bswap16(v)
296
#define ne32_to_le32(v) bswap32(v)
297
#define ne64_to_le64(v) bswap64(v)
298
#else
299
5.74M
#define ne16_to_be16(v) bswap16(v)
300
9.12M
#define ne32_to_be32(v) bswap32(v)
301
5.70M
#define ne64_to_be64(v) bswap64(v)
302
6.41M
#define ne16_to_le16(v) no_bswap16(v)
303
10.7M
#define ne32_to_le32(v) no_bswap32(v)
304
5.87M
#define ne64_to_le64(v) no_bswap64(v)
305
#endif
306
307
/*************************************************************************
308
// get/set 16/32/64
309
**************************************************************************/
310
311
REQUIRE_XE16
312
4.88M
inline bele_constexpr unsigned get_be16(const XE16 *p) noexcept {
313
4.88M
    return ne16_to_be16(get_ne16(p));
314
4.88M
}
unsigned int get_be16<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
312
4.78M
inline bele_constexpr unsigned get_be16(const XE16 *p) noexcept {
313
4.78M
    return ne16_to_be16(get_ne16(p));
314
4.78M
}
unsigned int get_be16<void, void>(void const*)
Line
Count
Source
312
97.0k
inline bele_constexpr unsigned get_be16(const XE16 *p) noexcept {
313
97.0k
    return ne16_to_be16(get_ne16(p));
314
97.0k
}
315
REQUIRE_XE32
316
8.09M
inline bele_constexpr unsigned get_be32(const XE32 *p) noexcept {
317
8.09M
    return ne32_to_be32(get_ne32(p));
318
8.09M
}
unsigned int get_be32<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
316
7.86M
inline bele_constexpr unsigned get_be32(const XE32 *p) noexcept {
317
7.86M
    return ne32_to_be32(get_ne32(p));
318
7.86M
}
unsigned int get_be32<void, void>(void const*)
Line
Count
Source
316
225k
inline bele_constexpr unsigned get_be32(const XE32 *p) noexcept {
317
225k
    return ne32_to_be32(get_ne32(p));
318
225k
}
319
REQUIRE_XE64
320
4.85M
inline bele_constexpr upx_uint64_t get_be64(const XE64 *p) noexcept {
321
4.85M
    return ne64_to_be64(get_ne64(p));
322
4.85M
}
unsigned long long get_be64<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
320
4.78M
inline bele_constexpr upx_uint64_t get_be64(const XE64 *p) noexcept {
321
4.78M
    return ne64_to_be64(get_ne64(p));
322
4.78M
}
unsigned long long get_be64<void, void>(void const*)
Line
Count
Source
320
65.1k
inline bele_constexpr upx_uint64_t get_be64(const XE64 *p) noexcept {
321
65.1k
    return ne64_to_be64(get_ne64(p));
322
65.1k
}
323
REQUIRE_XE16
324
5.38M
inline bele_constexpr unsigned get_le16(const XE16 *p) noexcept {
325
5.38M
    return ne16_to_le16(get_ne16(p));
326
5.38M
}
unsigned int get_le16<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
324
5.08M
inline bele_constexpr unsigned get_le16(const XE16 *p) noexcept {
325
5.08M
    return ne16_to_le16(get_ne16(p));
326
5.08M
}
unsigned int get_le16<void, void>(void const*)
Line
Count
Source
324
268k
inline bele_constexpr unsigned get_le16(const XE16 *p) noexcept {
325
268k
    return ne16_to_le16(get_ne16(p));
326
268k
}
unsigned int get_le16<LE16, LE16>(LE16 const*)
Line
Count
Source
324
30.0k
inline bele_constexpr unsigned get_le16(const XE16 *p) noexcept {
325
30.0k
    return ne16_to_le16(get_ne16(p));
326
30.0k
}
327
REQUIRE_XE32
328
6.58M
inline bele_constexpr unsigned get_le32(const XE32 *p) noexcept {
329
6.58M
    return ne32_to_le32(get_ne32(p));
330
6.58M
}
unsigned int get_le32<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
328
5.90M
inline bele_constexpr unsigned get_le32(const XE32 *p) noexcept {
329
5.90M
    return ne32_to_le32(get_ne32(p));
330
5.90M
}
unsigned int get_le32<void, void>(void const*)
Line
Count
Source
328
682k
inline bele_constexpr unsigned get_le32(const XE32 *p) noexcept {
329
682k
    return ne32_to_le32(get_ne32(p));
330
682k
}
unsigned int get_le32<unsigned int, unsigned int>(unsigned int const*)
Line
Count
Source
328
16
inline bele_constexpr unsigned get_le32(const XE32 *p) noexcept {
329
16
    return ne32_to_le32(get_ne32(p));
330
16
}
unsigned int get_le32<LE32, LE32>(LE32 const*)
Line
Count
Source
328
1.05k
inline bele_constexpr unsigned get_le32(const XE32 *p) noexcept {
329
1.05k
    return ne32_to_le32(get_ne32(p));
330
1.05k
}
Unexecuted instantiation: unsigned int get_le32<char, char>(char const*)
331
REQUIRE_XE64
332
5.02M
inline bele_constexpr upx_uint64_t get_le64(const XE64 *p) noexcept {
333
5.02M
    return ne64_to_le64(get_ne64(p));
334
5.02M
}
unsigned long long get_le64<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
332
4.87M
inline bele_constexpr upx_uint64_t get_le64(const XE64 *p) noexcept {
333
4.87M
    return ne64_to_le64(get_ne64(p));
334
4.87M
}
unsigned long long get_le64<void, void>(void const*)
Line
Count
Source
332
148k
inline bele_constexpr upx_uint64_t get_le64(const XE64 *p) noexcept {
333
148k
    return ne64_to_le64(get_ne64(p));
334
148k
}
335
336
REQUIRE_XE16
337
861k
inline bele_constexpr void set_be16(XE16 *p, unsigned v) noexcept { set_ne16(p, ne16_to_be16(v)); }
void set_be16<unsigned char, unsigned char>(unsigned char*, unsigned int)
Line
Count
Source
337
861k
inline bele_constexpr void set_be16(XE16 *p, unsigned v) noexcept { set_ne16(p, ne16_to_be16(v)); }
Unexecuted instantiation: void set_be16<void, void>(void*, unsigned int)
338
REQUIRE_XE32
339
1.03M
inline bele_constexpr void set_be32(XE32 *p, unsigned v) noexcept { set_ne32(p, ne32_to_be32(v)); }
void set_be32<unsigned char, unsigned char>(unsigned char*, unsigned int)
Line
Count
Source
339
1.03M
inline bele_constexpr void set_be32(XE32 *p, unsigned v) noexcept { set_ne32(p, ne32_to_be32(v)); }
Unexecuted instantiation: void set_be32<void, void>(void*, unsigned int)
Unexecuted instantiation: void set_be32<LE32, LE32>(LE32*, unsigned int)
Unexecuted instantiation: void set_be32<unsigned int, unsigned int>(unsigned int*, unsigned int)
340
REQUIRE_XE64
341
850k
inline bele_constexpr void set_be64(XE64 *p, upx_uint64_t v) noexcept {
342
850k
    set_ne64(p, ne64_to_be64(v));
343
850k
}
void set_be64<unsigned char, unsigned char>(unsigned char*, unsigned long long)
Line
Count
Source
341
850k
inline bele_constexpr void set_be64(XE64 *p, upx_uint64_t v) noexcept {
342
850k
    set_ne64(p, ne64_to_be64(v));
343
850k
}
Unexecuted instantiation: void set_be64<void, void>(void*, unsigned long long)
344
REQUIRE_XE16
345
1.02M
inline bele_constexpr void set_le16(XE16 *p, unsigned v) noexcept { set_ne16(p, ne16_to_le16(v)); }
void set_le16<unsigned char, unsigned char>(unsigned char*, unsigned int)
Line
Count
Source
345
1.02M
inline bele_constexpr void set_le16(XE16 *p, unsigned v) noexcept { set_ne16(p, ne16_to_le16(v)); }
Unexecuted instantiation: void set_le16<void, void>(void*, unsigned int)
Unexecuted instantiation: void set_le16<LE16, LE16>(LE16*, unsigned int)
346
REQUIRE_XE32
347
2.17M
inline bele_constexpr void set_le32(XE32 *p, unsigned v) noexcept { set_ne32(p, ne32_to_le32(v)); }
void set_le32<unsigned char, unsigned char>(unsigned char*, unsigned int)
Line
Count
Source
347
2.17M
inline bele_constexpr void set_le32(XE32 *p, unsigned v) noexcept { set_ne32(p, ne32_to_le32(v)); }
Unexecuted instantiation: void set_le32<void, void>(void*, unsigned int)
Unexecuted instantiation: void set_le32<LE32, LE32>(LE32*, unsigned int)
Unexecuted instantiation: void set_le32<unsigned int, unsigned int>(unsigned int*, unsigned int)
Unexecuted instantiation: void set_le32<char, char>(char*, unsigned int)
348
REQUIRE_XE64
349
850k
inline bele_constexpr void set_le64(XE64 *p, upx_uint64_t v) noexcept {
350
850k
    set_ne64(p, ne64_to_le64(v));
351
850k
}
void set_le64<unsigned char, unsigned char>(unsigned char*, unsigned long long)
Line
Count
Source
349
850k
inline bele_constexpr void set_le64(XE64 *p, upx_uint64_t v) noexcept {
350
850k
    set_ne64(p, ne64_to_le64(v));
351
850k
}
Unexecuted instantiation: void set_le64<void, void>(void*, unsigned long long)
352
353
/*************************************************************************
354
// get/set 24/26
355
**************************************************************************/
356
357
49.7k
inline constexpr unsigned get_be24(const byte *p) noexcept {
358
49.7k
    return upx::compile_time::get_be24(p);
359
49.7k
}
360
151k
inline constexpr unsigned get_le24(const byte *p) noexcept {
361
151k
    return upx::compile_time::get_le24(p);
362
151k
}
363
34.0k
inline constexpr void set_be24(byte *p, unsigned v) noexcept { upx::compile_time::set_be24(p, v); }
364
135k
inline constexpr void set_le24(byte *p, unsigned v) noexcept { upx::compile_time::set_le24(p, v); }
365
366
REQUIRE_XE24
367
15.6k
forceinline bele_constexpr unsigned get_be24(const XE24 *p) noexcept {
368
15.6k
    return get_be24(upx::ptr_static_cast<const byte *>(p));
369
15.6k
}
370
REQUIRE_XE24
371
15.6k
forceinline bele_constexpr unsigned get_le24(const XE24 *p) noexcept {
372
15.6k
    return get_le24(upx::ptr_static_cast<const byte *>(p));
373
15.6k
}
374
REQUIRE_XE24
375
0
forceinline bele_constexpr void set_be24(XE24 *p, unsigned v) noexcept {
376
0
    set_be24(upx::ptr_static_cast<byte *>(p), v);
377
0
}
378
REQUIRE_XE24
379
0
forceinline bele_constexpr void set_le24(XE24 *p, unsigned v) noexcept {
380
0
    set_le24(upx::ptr_static_cast<byte *>(p), v);
381
0
}
382
383
REQUIRE_XE32
384
659k
inline bele_constexpr unsigned get_le26(const XE32 *p) noexcept { return get_le32(p) & 0x03ffffff; }
unsigned int get_le26<void, void>(void const*)
Line
Count
Source
384
46.9k
inline bele_constexpr unsigned get_le26(const XE32 *p) noexcept { return get_le32(p) & 0x03ffffff; }
unsigned int get_le26<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
384
612k
inline bele_constexpr unsigned get_le26(const XE32 *p) noexcept { return get_le32(p) & 0x03ffffff; }
385
REQUIRE_XE32
386
inline bele_constexpr unsigned get_le19_5(const XE32 *p) noexcept {
387
    return (get_le32(p) >> 5) & 0x0007ffff;
388
}
389
REQUIRE_XE32
390
inline bele_constexpr unsigned get_le14_5(const XE32 *p) noexcept {
391
    return (get_le32(p) >> 5) & 0x00003fff;
392
}
393
394
REQUIRE_XE32
395
644k
inline bele_constexpr void set_le26(XE32 *p, unsigned v) noexcept {
396
    // preserve the top 6 bits
397
    //   set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff));
398
    // optimized version, saving a runtime bswap32
399
644k
    set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) |
400
644k
                    (ne32_to_le32(v) & ne32_to_le32(0x03ffffff)));
401
644k
}
void set_le26<void, void>(void*, unsigned int)
Line
Count
Source
395
31.3k
inline bele_constexpr void set_le26(XE32 *p, unsigned v) noexcept {
396
    // preserve the top 6 bits
397
    //   set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff));
398
    // optimized version, saving a runtime bswap32
399
31.3k
    set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) |
400
31.3k
                    (ne32_to_le32(v) & ne32_to_le32(0x03ffffff)));
401
31.3k
}
void set_le26<unsigned char, unsigned char>(unsigned char*, unsigned int)
Line
Count
Source
395
612k
inline bele_constexpr void set_le26(XE32 *p, unsigned v) noexcept {
396
    // preserve the top 6 bits
397
    //   set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff));
398
    // optimized version, saving a runtime bswap32
399
612k
    set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) |
400
612k
                    (ne32_to_le32(v) & ne32_to_le32(0x03ffffff)));
401
612k
}
402
REQUIRE_XE32
403
inline bele_constexpr void set_le19_5(XE32 *p, unsigned v) noexcept {
404
    set_le32(p, (get_le32(p) & 0xff00001f) | ((v & 0x0007ffff) << 5));
405
}
406
REQUIRE_XE32
407
inline bele_constexpr void set_le14_5(XE32 *p, unsigned v) noexcept {
408
    set_le32(p, (get_le32(p) & 0xfff8001f) | ((v & 0x00003fff) << 5));
409
}
410
411
/*************************************************************************
412
// get signed values
413
**************************************************************************/
414
415
93.9k
forceinline constexpr int sign_extend32(unsigned v, unsigned bits) noexcept {
416
#if (ACC_ARCH_M68K) // no barrel shifter
417
    const unsigned sign_bit = 1u << (bits - 1);
418
    return ACC_ICAST(int, (v & (sign_bit - 1)) - (v & sign_bit));
419
#else
420
93.9k
    return ACC_ICAST(int, v << (32 - bits)) >> (32 - bits);
421
93.9k
#endif
422
93.9k
}
423
424
46.9k
forceinline constexpr upx_int64_t sign_extend64(upx_uint64_t v, unsigned bits) noexcept {
425
#if (ACC_ARCH_M68K) // no barrel shifter
426
    const upx_uint64_t sign_bit = upx_uint64_t(1) << (bits - 1);
427
    return ACC_ICAST(upx_int64_t, (v & (sign_bit - 1)) - (v & sign_bit));
428
#else
429
46.9k
    return ACC_ICAST(upx_int64_t, v << (64 - bits)) >> (64 - bits);
430
46.9k
#endif
431
46.9k
}
432
433
REQUIRE_XE16
434
31.3k
inline bele_constexpr int get_be16_signed(const XE16 *p) noexcept {
435
31.3k
    unsigned v = get_be16(p);
436
31.3k
    return sign_extend32(v, 16);
437
31.3k
}
Unexecuted instantiation: int get_be16_signed<void, void>(void const*)
int get_be16_signed<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
434
31.3k
inline bele_constexpr int get_be16_signed(const XE16 *p) noexcept {
435
31.3k
    unsigned v = get_be16(p);
436
31.3k
    return sign_extend32(v, 16);
437
31.3k
}
438
439
REQUIRE_XE24
440
0
inline bele_constexpr int get_be24_signed(const XE24 *p) noexcept {
441
0
    unsigned v = get_be24(p);
442
0
    return sign_extend32(v, 24);
443
0
}
Unexecuted instantiation: int get_be24_signed<void, void>(void const*)
Unexecuted instantiation: int get_be24_signed<unsigned char, unsigned char>(unsigned char const*)
444
445
REQUIRE_XE32
446
31.3k
inline bele_constexpr int get_be32_signed(const XE32 *p) noexcept {
447
31.3k
    unsigned v = get_be32(p);
448
31.3k
    return sign_extend32(v, 32);
449
31.3k
}
Unexecuted instantiation: int get_be32_signed<void, void>(void const*)
int get_be32_signed<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
446
31.3k
inline bele_constexpr int get_be32_signed(const XE32 *p) noexcept {
447
31.3k
    unsigned v = get_be32(p);
448
31.3k
    return sign_extend32(v, 32);
449
31.3k
}
450
451
REQUIRE_XE64
452
31.3k
inline bele_constexpr upx_int64_t get_be64_signed(const XE64 *p) noexcept {
453
31.3k
    upx_uint64_t v = get_be64(p);
454
31.3k
    return sign_extend64(v, 64);
455
31.3k
}
Unexecuted instantiation: long long get_be64_signed<void, void>(void const*)
long long get_be64_signed<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
452
31.3k
inline bele_constexpr upx_int64_t get_be64_signed(const XE64 *p) noexcept {
453
31.3k
    upx_uint64_t v = get_be64(p);
454
31.3k
    return sign_extend64(v, 64);
455
31.3k
}
456
457
REQUIRE_XE16
458
15.6k
inline bele_constexpr int get_le16_signed(const XE16 *p) noexcept {
459
15.6k
    unsigned v = get_le16(p);
460
15.6k
    return sign_extend32(v, 16);
461
15.6k
}
Unexecuted instantiation: int get_le16_signed<void, void>(void const*)
int get_le16_signed<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
458
15.6k
inline bele_constexpr int get_le16_signed(const XE16 *p) noexcept {
459
15.6k
    unsigned v = get_le16(p);
460
15.6k
    return sign_extend32(v, 16);
461
15.6k
}
462
463
REQUIRE_XE24
464
0
inline bele_constexpr int get_le24_signed(const XE24 *p) noexcept {
465
0
    unsigned v = get_le24(p);
466
0
    return sign_extend32(v, 24);
467
0
}
Unexecuted instantiation: int get_le24_signed<void, void>(void const*)
Unexecuted instantiation: int get_le24_signed<unsigned char, unsigned char>(unsigned char const*)
468
469
REQUIRE_XE32
470
15.6k
inline bele_constexpr int get_le32_signed(const XE32 *p) noexcept {
471
15.6k
    unsigned v = get_le32(p);
472
15.6k
    return sign_extend32(v, 32);
473
15.6k
}
Unexecuted instantiation: int get_le32_signed<void, void>(void const*)
int get_le32_signed<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
470
15.6k
inline bele_constexpr int get_le32_signed(const XE32 *p) noexcept {
471
15.6k
    unsigned v = get_le32(p);
472
15.6k
    return sign_extend32(v, 32);
473
15.6k
}
474
475
REQUIRE_XE64
476
15.6k
inline bele_constexpr upx_int64_t get_le64_signed(const XE64 *p) noexcept {
477
15.6k
    upx_uint64_t v = get_le64(p);
478
15.6k
    return sign_extend64(v, 64);
479
15.6k
}
Unexecuted instantiation: long long get_le64_signed<void, void>(void const*)
long long get_le64_signed<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
476
15.6k
inline bele_constexpr upx_int64_t get_le64_signed(const XE64 *p) noexcept {
477
15.6k
    upx_uint64_t v = get_le64(p);
478
15.6k
    return sign_extend64(v, 64);
479
15.6k
}
480
481
/*************************************************************************
482
// classes for portable unaligned access
483
//
484
// Note: these classes must be PODs (Plain Old Data), i.e. no
485
//   constructor, no destructor, no virtual functions and no default
486
//   assignment operator, and all fields must be public
487
**************************************************************************/
488
489
struct alignas(1) BE16 final {
490
    typedef unsigned integral_conversion_type; // automatic conversion to unsigned
491
    byte d[2];
492
493
0
    static forceinline constexpr BE16 make(const BE16 &x) noexcept { return x; }
494
0
    static forceinline bele_constexpr BE16 make(unsigned v) noexcept {
495
0
        BE16 x = {};
496
0
        set_be16(x.d, v);
497
0
        return x;
498
0
    }
499
500
4.46M
    forceinline bele_constexpr operator unsigned() const noexcept { return get_be16(d); }
501
502
532k
    forceinline bele_constexpr BE16 &operator=(unsigned v) noexcept {
503
532k
        set_be16(d, v);
504
532k
        return *this;
505
532k
    }
506
46.9k
    BE16 &operator+=(unsigned v) noexcept {
507
46.9k
        set_be16(d, get_be16(d) + v);
508
46.9k
        return *this;
509
46.9k
    }
510
78.2k
    BE16 &operator-=(unsigned v) noexcept {
511
78.2k
        set_be16(d, get_be16(d) - v);
512
78.2k
        return *this;
513
78.2k
    }
514
31.3k
    BE16 &operator*=(unsigned v) noexcept {
515
31.3k
        set_be16(d, get_be16(d) * v);
516
31.3k
        return *this;
517
31.3k
    }
518
31.3k
    BE16 &operator/=(unsigned v) noexcept {
519
31.3k
        set_be16(d, get_be16(d) / v);
520
31.3k
        return *this;
521
31.3k
    }
522
15.6k
    BE16 &operator&=(unsigned v) noexcept {
523
15.6k
        set_be16(d, get_be16(d) & v);
524
15.6k
        return *this;
525
15.6k
    }
526
15.6k
    BE16 &operator|=(unsigned v) noexcept {
527
15.6k
        set_be16(d, get_be16(d) | v);
528
15.6k
        return *this;
529
15.6k
    }
530
15.6k
    BE16 &operator^=(unsigned v) noexcept {
531
15.6k
        set_be16(d, get_be16(d) ^ v);
532
15.6k
        return *this;
533
15.6k
    }
534
15.6k
    BE16 &operator<<=(unsigned v) noexcept {
535
15.6k
        set_be16(d, get_be16(d) << v);
536
15.6k
        return *this;
537
15.6k
    }
538
15.6k
    BE16 &operator>>=(unsigned v) noexcept {
539
15.6k
        set_be16(d, get_be16(d) >> v);
540
15.6k
        return *this;
541
15.6k
    }
542
543
375k
    bele_constexpr bool operator==(const BE16 &x) const noexcept {
544
375k
#if defined(upx_is_constant_evaluated)
545
375k
        if (upx_is_constant_evaluated())
546
0
            return upx::compile_time::mem_eq(d, x.d, sizeof(d));
547
375k
        else
548
375k
#endif
549
375k
            return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
550
375k
    }
551
344k
    bele_constexpr bool operator<(const BE16 &x) const noexcept {
552
344k
        return unsigned(*this) < unsigned(x);
553
344k
    }
554
};
555
556
struct alignas(1) BE32 final {
557
    typedef unsigned integral_conversion_type; // automatic conversion to unsigned
558
    byte d[4];
559
560
0
    static forceinline constexpr BE32 make(const BE32 &x) noexcept { return x; }
561
0
    static forceinline bele_constexpr BE32 make(unsigned v) noexcept {
562
0
        BE32 x = {};
563
0
        set_be32(x.d, v);
564
0
        return x;
565
0
    }
566
567
4.48M
    forceinline bele_constexpr operator unsigned() const noexcept { return get_be32(d); }
568
569
547k
    forceinline bele_constexpr BE32 &operator=(unsigned v) noexcept {
570
547k
        set_be32(d, v);
571
547k
        return *this;
572
547k
    }
573
46.9k
    BE32 &operator+=(unsigned v) noexcept {
574
46.9k
        set_be32(d, get_be32(d) + v);
575
46.9k
        return *this;
576
46.9k
    }
577
93.9k
    BE32 &operator-=(unsigned v) noexcept {
578
93.9k
        set_be32(d, get_be32(d) - v);
579
93.9k
        return *this;
580
93.9k
    }
581
31.3k
    BE32 &operator*=(unsigned v) noexcept {
582
31.3k
        set_be32(d, get_be32(d) * v);
583
31.3k
        return *this;
584
31.3k
    }
585
31.3k
    BE32 &operator/=(unsigned v) noexcept {
586
31.3k
        set_be32(d, get_be32(d) / v);
587
31.3k
        return *this;
588
31.3k
    }
589
15.6k
    BE32 &operator&=(unsigned v) noexcept {
590
15.6k
        set_be32(d, get_be32(d) & v);
591
15.6k
        return *this;
592
15.6k
    }
593
15.6k
    BE32 &operator|=(unsigned v) noexcept {
594
15.6k
        set_be32(d, get_be32(d) | v);
595
15.6k
        return *this;
596
15.6k
    }
597
15.6k
    BE32 &operator^=(unsigned v) noexcept {
598
15.6k
        set_be32(d, get_be32(d) ^ v);
599
15.6k
        return *this;
600
15.6k
    }
601
15.6k
    BE32 &operator<<=(unsigned v) noexcept {
602
15.6k
        set_be32(d, get_be32(d) << v);
603
15.6k
        return *this;
604
15.6k
    }
605
15.6k
    BE32 &operator>>=(unsigned v) noexcept {
606
15.6k
        set_be32(d, get_be32(d) >> v);
607
15.6k
        return *this;
608
15.6k
    }
609
610
375k
    bele_constexpr bool operator==(const BE32 &x) const noexcept {
611
375k
#if defined(upx_is_constant_evaluated)
612
375k
        if (upx_is_constant_evaluated())
613
0
            return upx::compile_time::mem_eq(d, x.d, sizeof(d));
614
375k
        else
615
375k
#endif
616
375k
            return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
617
375k
    }
618
344k
    bele_constexpr bool operator<(const BE32 &x) const noexcept {
619
344k
        return unsigned(*this) < unsigned(x);
620
344k
    }
621
};
622
623
struct alignas(1) BE64 final {
624
    typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t
625
    byte d[8];
626
627
0
    static forceinline constexpr BE64 make(const BE64 &x) noexcept { return x; }
628
0
    static forceinline bele_constexpr BE64 make(upx_uint64_t v) noexcept {
629
0
        BE64 x = {};
630
0
        set_be64(x.d, v);
631
0
        return x;
632
0
    }
633
634
4.46M
    forceinline bele_constexpr operator upx_uint64_t() const noexcept { return get_be64(d); }
635
636
547k
    forceinline bele_constexpr BE64 &operator=(upx_uint64_t v) noexcept {
637
547k
        set_be64(d, v);
638
547k
        return *this;
639
547k
    }
640
46.9k
    BE64 &operator+=(upx_uint64_t v) noexcept {
641
46.9k
        set_be64(d, get_be64(d) + v);
642
46.9k
        return *this;
643
46.9k
    }
644
93.9k
    BE64 &operator-=(upx_uint64_t v) noexcept {
645
93.9k
        set_be64(d, get_be64(d) - v);
646
93.9k
        return *this;
647
93.9k
    }
648
31.3k
    BE64 &operator*=(upx_uint64_t v) noexcept {
649
31.3k
        set_be64(d, get_be64(d) * v);
650
31.3k
        return *this;
651
31.3k
    }
652
31.3k
    BE64 &operator/=(upx_uint64_t v) noexcept {
653
31.3k
        set_be64(d, get_be64(d) / v);
654
31.3k
        return *this;
655
31.3k
    }
656
15.6k
    BE64 &operator&=(upx_uint64_t v) noexcept {
657
15.6k
        set_be64(d, get_be64(d) & v);
658
15.6k
        return *this;
659
15.6k
    }
660
15.6k
    BE64 &operator|=(upx_uint64_t v) noexcept {
661
15.6k
        set_be64(d, get_be64(d) | v);
662
15.6k
        return *this;
663
15.6k
    }
664
15.6k
    BE64 &operator^=(upx_uint64_t v) noexcept {
665
15.6k
        set_be64(d, get_be64(d) ^ v);
666
15.6k
        return *this;
667
15.6k
    }
668
15.6k
    BE64 &operator<<=(unsigned v) noexcept {
669
15.6k
        set_be64(d, get_be64(d) << v);
670
15.6k
        return *this;
671
15.6k
    }
672
15.6k
    BE64 &operator>>=(unsigned v) noexcept {
673
15.6k
        set_be64(d, get_be64(d) >> v);
674
15.6k
        return *this;
675
15.6k
    }
676
677
375k
    bele_constexpr bool operator==(const BE64 &x) const noexcept {
678
375k
#if defined(upx_is_constant_evaluated)
679
375k
        if (upx_is_constant_evaluated())
680
0
            return upx::compile_time::mem_eq(d, x.d, sizeof(d));
681
375k
        else
682
375k
#endif
683
375k
            return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
684
375k
    }
685
344k
    bele_constexpr bool operator<(const BE64 &x) const noexcept {
686
344k
        return upx_uint64_t(*this) < upx_uint64_t(x);
687
344k
    }
688
};
689
690
struct alignas(1) LE16 final {
691
    typedef unsigned integral_conversion_type; // automatic conversion to unsigned
692
    byte d[2];
693
694
0
    static forceinline constexpr LE16 make(const LE16 &x) noexcept { return x; }
695
0
    static forceinline bele_constexpr LE16 make(unsigned v) noexcept {
696
0
        LE16 x = {};
697
0
        set_le16(x.d, v);
698
0
        return x;
699
0
    }
700
701
4.54M
    forceinline bele_constexpr operator unsigned() const noexcept { return get_le16(d); }
702
703
550k
    forceinline bele_constexpr LE16 &operator=(unsigned v) noexcept {
704
550k
        set_le16(d, v);
705
550k
        return *this;
706
550k
    }
707
46.9k
    LE16 &operator+=(unsigned v) noexcept {
708
46.9k
        set_le16(d, get_le16(d) + v);
709
46.9k
        return *this;
710
46.9k
    }
711
78.2k
    LE16 &operator-=(unsigned v) noexcept {
712
78.2k
        set_le16(d, get_le16(d) - v);
713
78.2k
        return *this;
714
78.2k
    }
715
31.3k
    LE16 &operator*=(unsigned v) noexcept {
716
31.3k
        set_le16(d, get_le16(d) * v);
717
31.3k
        return *this;
718
31.3k
    }
719
31.3k
    LE16 &operator/=(unsigned v) noexcept {
720
31.3k
        set_le16(d, get_le16(d) / v);
721
31.3k
        return *this;
722
31.3k
    }
723
15.6k
    LE16 &operator&=(unsigned v) noexcept {
724
15.6k
        set_le16(d, get_le16(d) & v);
725
15.6k
        return *this;
726
15.6k
    }
727
15.6k
    LE16 &operator|=(unsigned v) noexcept {
728
15.6k
        set_le16(d, get_le16(d) | v);
729
15.6k
        return *this;
730
15.6k
    }
731
15.6k
    LE16 &operator^=(unsigned v) noexcept {
732
15.6k
        set_le16(d, get_le16(d) ^ v);
733
15.6k
        return *this;
734
15.6k
    }
735
15.6k
    LE16 &operator<<=(unsigned v) noexcept {
736
15.6k
        set_le16(d, get_le16(d) << v);
737
15.6k
        return *this;
738
15.6k
    }
739
15.6k
    LE16 &operator>>=(unsigned v) noexcept {
740
15.6k
        set_le16(d, get_le16(d) >> v);
741
15.6k
        return *this;
742
15.6k
    }
743
744
375k
    bele_constexpr bool operator==(const LE16 &x) const noexcept {
745
375k
#if defined(upx_is_constant_evaluated)
746
375k
        if (upx_is_constant_evaluated())
747
0
            return upx::compile_time::mem_eq(d, x.d, sizeof(d));
748
375k
        else
749
375k
#endif
750
375k
            return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
751
375k
    }
752
344k
    bele_constexpr bool operator<(const LE16 &x) const noexcept {
753
344k
        return unsigned(*this) < unsigned(x);
754
344k
    }
755
};
756
757
struct alignas(1) LE32 final {
758
    typedef unsigned integral_conversion_type; // automatic conversion to unsigned
759
    byte d[4];
760
761
0
    static forceinline constexpr LE32 make(const LE32 &x) noexcept { return x; }
762
0
    static forceinline bele_constexpr LE32 make(unsigned v) noexcept {
763
0
        LE32 x = {};
764
0
        set_le32(x.d, v);
765
0
        return x;
766
0
    }
767
768
4.73M
    forceinline bele_constexpr operator unsigned() const noexcept { return get_le32(d); }
769
770
567k
    forceinline bele_constexpr LE32 &operator=(unsigned v) noexcept {
771
567k
        set_le32(d, v);
772
567k
        return *this;
773
567k
    }
774
65.7k
    LE32 &operator+=(unsigned v) noexcept {
775
65.7k
        set_le32(d, get_le32(d) + v);
776
65.7k
        return *this;
777
65.7k
    }
778
93.9k
    LE32 &operator-=(unsigned v) noexcept {
779
93.9k
        set_le32(d, get_le32(d) - v);
780
93.9k
        return *this;
781
93.9k
    }
782
31.3k
    LE32 &operator*=(unsigned v) noexcept {
783
31.3k
        set_le32(d, get_le32(d) * v);
784
31.3k
        return *this;
785
31.3k
    }
786
31.3k
    LE32 &operator/=(unsigned v) noexcept {
787
31.3k
        set_le32(d, get_le32(d) / v);
788
31.3k
        return *this;
789
31.3k
    }
790
15.6k
    LE32 &operator&=(unsigned v) noexcept {
791
15.6k
        set_le32(d, get_le32(d) & v);
792
15.6k
        return *this;
793
15.6k
    }
794
15.6k
    LE32 &operator|=(unsigned v) noexcept {
795
15.6k
        set_le32(d, get_le32(d) | v);
796
15.6k
        return *this;
797
15.6k
    }
798
15.6k
    LE32 &operator^=(unsigned v) noexcept {
799
15.6k
        set_le32(d, get_le32(d) ^ v);
800
15.6k
        return *this;
801
15.6k
    }
802
15.6k
    LE32 &operator<<=(unsigned v) noexcept {
803
15.6k
        set_le32(d, get_le32(d) << v);
804
15.6k
        return *this;
805
15.6k
    }
806
15.6k
    LE32 &operator>>=(unsigned v) noexcept {
807
15.6k
        set_le32(d, get_le32(d) >> v);
808
15.6k
        return *this;
809
15.6k
    }
810
811
376k
    bele_constexpr bool operator==(const LE32 &x) const noexcept {
812
376k
#if defined(upx_is_constant_evaluated)
813
376k
        if (upx_is_constant_evaluated())
814
0
            return upx::compile_time::mem_eq(d, x.d, sizeof(d));
815
376k
        else
816
376k
#endif
817
376k
            return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
818
376k
    }
819
345k
    bele_constexpr bool operator<(const LE32 &x) const noexcept {
820
345k
        return unsigned(*this) < unsigned(x);
821
345k
    }
822
};
823
824
struct alignas(1) LE64 final {
825
    typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t
826
    byte d[8];
827
828
0
    static forceinline constexpr LE64 make(const LE64 &x) noexcept { return x; }
829
0
    static forceinline bele_constexpr LE64 make(upx_uint64_t v) noexcept {
830
0
        LE64 x = {};
831
0
        set_le64(x.d, v);
832
0
        return x;
833
0
    }
834
835
4.55M
    forceinline bele_constexpr operator upx_uint64_t() const noexcept { return get_le64(d); }
836
837
547k
    forceinline bele_constexpr LE64 &operator=(upx_uint64_t v) noexcept {
838
547k
        set_le64(d, v);
839
547k
        return *this;
840
547k
    }
841
46.9k
    LE64 &operator+=(upx_uint64_t v) noexcept {
842
46.9k
        set_le64(d, get_le64(d) + v);
843
46.9k
        return *this;
844
46.9k
    }
845
93.9k
    LE64 &operator-=(upx_uint64_t v) noexcept {
846
93.9k
        set_le64(d, get_le64(d) - v);
847
93.9k
        return *this;
848
93.9k
    }
849
31.3k
    LE64 &operator*=(upx_uint64_t v) noexcept {
850
31.3k
        set_le64(d, get_le64(d) * v);
851
31.3k
        return *this;
852
31.3k
    }
853
31.3k
    LE64 &operator/=(upx_uint64_t v) noexcept {
854
31.3k
        set_le64(d, get_le64(d) / v);
855
31.3k
        return *this;
856
31.3k
    }
857
15.6k
    LE64 &operator&=(upx_uint64_t v) noexcept {
858
15.6k
        set_le64(d, get_le64(d) & v);
859
15.6k
        return *this;
860
15.6k
    }
861
15.6k
    LE64 &operator|=(upx_uint64_t v) noexcept {
862
15.6k
        set_le64(d, get_le64(d) | v);
863
15.6k
        return *this;
864
15.6k
    }
865
15.6k
    LE64 &operator^=(upx_uint64_t v) noexcept {
866
15.6k
        set_le64(d, get_le64(d) ^ v);
867
15.6k
        return *this;
868
15.6k
    }
869
15.6k
    LE64 &operator<<=(unsigned v) noexcept {
870
15.6k
        set_le64(d, get_le64(d) << v);
871
15.6k
        return *this;
872
15.6k
    }
873
15.6k
    LE64 &operator>>=(unsigned v) noexcept {
874
15.6k
        set_le64(d, get_le64(d) >> v);
875
15.6k
        return *this;
876
15.6k
    }
877
878
375k
    bele_constexpr bool operator==(const LE64 &x) const noexcept {
879
375k
#if defined(upx_is_constant_evaluated)
880
375k
        if (upx_is_constant_evaluated())
881
0
            return upx::compile_time::mem_eq(d, x.d, sizeof(d));
882
375k
        else
883
375k
#endif
884
375k
            return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
885
375k
    }
886
344k
    bele_constexpr bool operator<(const LE64 &x) const noexcept {
887
344k
        return upx_uint64_t(*this) < upx_uint64_t(x);
888
344k
    }
889
};
890
891
/*************************************************************************
892
// global operators (pointer addition/subtraction)
893
**************************************************************************/
894
895
template <class T>
896
inline bele_constexpr T *operator+(T *ptr, const BE16 &v) noexcept {
897
    return ptr + unsigned(v);
898
}
899
template <class T>
900
inline bele_constexpr T *operator-(T *ptr, const BE16 &v) noexcept {
901
    return ptr - unsigned(v);
902
}
903
template <class T>
904
910
inline bele_constexpr T *operator+(T *ptr, const BE32 &v) noexcept {
905
910
    return ptr + unsigned(v);
906
910
}
907
template <class T>
908
inline bele_constexpr T *operator-(T *ptr, const BE32 &v) noexcept {
909
    return ptr - unsigned(v);
910
}
911
template <class T>
912
inline bele_constexpr T *operator+(T *ptr, const LE16 &v) noexcept {
913
    return ptr + unsigned(v);
914
}
915
template <class T>
916
inline bele_constexpr T *operator-(T *ptr, const LE16 &v) noexcept {
917
    return ptr - unsigned(v);
918
}
919
template <class T>
920
2.44k
inline bele_constexpr T *operator+(T *ptr, const LE32 &v) noexcept {
921
2.44k
    return ptr + unsigned(v);
922
2.44k
}
unsigned int* operator+<unsigned int>(unsigned int*, LE32 const&)
Line
Count
Source
920
8
inline bele_constexpr T *operator+(T *ptr, const LE32 &v) noexcept {
921
8
    return ptr + unsigned(v);
922
8
}
char* operator+<char>(char*, LE32 const&)
Line
Count
Source
920
2.44k
inline bele_constexpr T *operator+(T *ptr, const LE32 &v) noexcept {
921
2.44k
    return ptr + unsigned(v);
922
2.44k
}
923
template <class T>
924
0
inline bele_constexpr T *operator-(T *ptr, const LE32 &v) noexcept {
925
0
    return ptr - unsigned(v);
926
0
}
927
928
// these are not implemented on purpose and will cause errors
929
template <class T>
930
T *operator+(T *ptr, const BE64 &v) noexcept DELETED_FUNCTION;
931
template <class T>
932
T *operator-(T *ptr, const BE64 &v) noexcept DELETED_FUNCTION;
933
template <class T>
934
T *operator+(T *ptr, const LE64 &v) noexcept DELETED_FUNCTION;
935
template <class T>
936
T *operator-(T *ptr, const LE64 &v) noexcept DELETED_FUNCTION;
937
938
#if !ALLOW_INT_PLUS_MEMBUFFER
939
template <class T>
940
T *operator+(const BE16 &v, T *ptr) noexcept DELETED_FUNCTION;
941
template <class T>
942
T *operator+(const BE32 &v, T *ptr) noexcept DELETED_FUNCTION;
943
template <class T>
944
T *operator+(const LE16 &v, T *ptr) noexcept DELETED_FUNCTION;
945
template <class T>
946
T *operator+(const LE32 &v, T *ptr) noexcept DELETED_FUNCTION;
947
#endif // ALLOW_INT_PLUS_MEMBUFFER
948
949
template <class T>
950
T *operator+(const BE64 &v, T *ptr) noexcept DELETED_FUNCTION;
951
template <class T>
952
T *operator+(const LE64 &v, T *ptr) noexcept DELETED_FUNCTION;
953
954
/*************************************************************************
955
// some global overloads
956
**************************************************************************/
957
958
namespace upx {
959
960
#define REQUIRE_UINT32                                                                             \
961
    template <class T, class = std::enable_if_t<std::is_same_v<T, upx_uint32_t>, T> >
962
#define REQUIRE_UINT64                                                                             \
963
    template <class T, class = std::enable_if_t<std::is_same_v<T, upx_uint64_t>, T> >
964
965
REQUIRE_UINT32
966
inline bele_constexpr T align_down(const T &a, const BE32 &b) noexcept {
967
    return align_down(a, T(b));
968
}
969
REQUIRE_UINT32
970
inline bele_constexpr T align_down(const BE32 &a, const T &b) noexcept {
971
    return align_down(T(a), b);
972
}
973
REQUIRE_UINT32
974
inline bele_constexpr T align_down(const T &a, const LE32 &b) noexcept {
975
    return align_down(a, T(b));
976
}
977
REQUIRE_UINT32
978
inline bele_constexpr T align_down(const LE32 &a, const T &b) noexcept {
979
    return align_down(T(a), b);
980
}
981
982
REQUIRE_UINT32
983
88
inline bele_constexpr T align_up(const T &a, const LE32 &b) noexcept { return align_up(a, T(b)); }
984
REQUIRE_UINT32
985
22
inline bele_constexpr T align_up(const LE32 &a, const T &b) noexcept { return align_up(T(a), b); }
986
REQUIRE_UINT32
987
inline bele_constexpr T align_up(const T &a, const BE32 &b) noexcept { return align_up(a, T(b)); }
988
REQUIRE_UINT32
989
inline bele_constexpr T align_up(const BE32 &a, const T &b) noexcept { return align_up(T(a), b); }
990
991
REQUIRE_UINT32
992
125k
inline bele_constexpr T min(const T &a, const BE16 &b) noexcept { return min(a, T(b)); }
993
REQUIRE_UINT32
994
125k
inline bele_constexpr T min(const BE16 &a, const T &b) noexcept { return min(T(a), b); }
995
REQUIRE_UINT32
996
125k
inline bele_constexpr T min(const T &a, const BE32 &b) noexcept { return min(a, T(b)); }
997
REQUIRE_UINT32
998
125k
inline bele_constexpr T min(const BE32 &a, const T &b) noexcept { return min(T(a), b); }
999
REQUIRE_UINT64
1000
125k
inline bele_constexpr T min(const T &a, const BE64 &b) noexcept { return min(a, T(b)); }
1001
REQUIRE_UINT64
1002
125k
inline bele_constexpr T min(const BE64 &a, const T &b) noexcept { return min(T(a), b); }
1003
REQUIRE_UINT32
1004
125k
inline bele_constexpr T min(const T &a, const LE16 &b) noexcept { return min(a, T(b)); }
1005
REQUIRE_UINT32
1006
125k
inline bele_constexpr T min(const LE16 &a, const T &b) noexcept { return min(T(a), b); }
1007
REQUIRE_UINT32
1008
125k
inline bele_constexpr T min(const T &a, const LE32 &b) noexcept { return min(a, T(b)); }
1009
REQUIRE_UINT32
1010
125k
inline bele_constexpr T min(const LE32 &a, const T &b) noexcept { return min(T(a), b); }
1011
REQUIRE_UINT64
1012
125k
inline bele_constexpr T min(const T &a, const LE64 &b) noexcept { return min(a, T(b)); }
1013
REQUIRE_UINT64
1014
125k
inline bele_constexpr T min(const LE64 &a, const T &b) noexcept { return min(T(a), b); }
1015
1016
REQUIRE_UINT32
1017
125k
inline bele_constexpr T max(const T &a, const BE16 &b) noexcept { return max(a, T(b)); }
1018
REQUIRE_UINT32
1019
125k
inline bele_constexpr T max(const BE16 &a, const T &b) noexcept { return max(T(a), b); }
1020
REQUIRE_UINT32
1021
125k
inline bele_constexpr T max(const T &a, const BE32 &b) noexcept { return max(a, T(b)); }
1022
REQUIRE_UINT32
1023
125k
inline bele_constexpr T max(const BE32 &a, const T &b) noexcept { return max(T(a), b); }
1024
REQUIRE_UINT64
1025
125k
inline bele_constexpr T max(const T &a, const BE64 &b) noexcept { return max(a, T(b)); }
1026
REQUIRE_UINT64
1027
125k
inline bele_constexpr T max(const BE64 &a, const T &b) noexcept { return max(T(a), b); }
1028
REQUIRE_UINT32
1029
125k
inline bele_constexpr T max(const T &a, const LE16 &b) noexcept { return max(a, T(b)); }
1030
REQUIRE_UINT32
1031
125k
inline bele_constexpr T max(const LE16 &a, const T &b) noexcept { return max(T(a), b); }
1032
REQUIRE_UINT32
1033
125k
inline bele_constexpr T max(const T &a, const LE32 &b) noexcept { return max(a, T(b)); }
1034
REQUIRE_UINT32
1035
125k
inline bele_constexpr T max(const LE32 &a, const T &b) noexcept { return max(T(a), b); }
1036
REQUIRE_UINT64
1037
125k
inline bele_constexpr T max(const T &a, const LE64 &b) noexcept { return max(a, T(b)); }
1038
REQUIRE_UINT64
1039
125k
inline bele_constexpr T max(const LE64 &a, const T &b) noexcept { return max(T(a), b); }
1040
1041
#undef REQUIRE_UINT32
1042
#undef REQUIRE_UINT64
1043
1044
} // namespace upx
1045
1046
/*************************************************************************
1047
// misc support
1048
**************************************************************************/
1049
1050
// for use with qsort()
1051
extern "C" {
1052
int __acc_cdecl_qsort be16_compare(const void *, const void *);
1053
int __acc_cdecl_qsort be24_compare(const void *, const void *);
1054
int __acc_cdecl_qsort be32_compare(const void *, const void *);
1055
int __acc_cdecl_qsort be64_compare(const void *, const void *);
1056
int __acc_cdecl_qsort le16_compare(const void *, const void *);
1057
int __acc_cdecl_qsort le24_compare(const void *, const void *);
1058
int __acc_cdecl_qsort le32_compare(const void *, const void *);
1059
int __acc_cdecl_qsort le64_compare(const void *, const void *);
1060
int __acc_cdecl_qsort be16_compare_signed(const void *, const void *);
1061
int __acc_cdecl_qsort be24_compare_signed(const void *, const void *);
1062
int __acc_cdecl_qsort be32_compare_signed(const void *, const void *);
1063
int __acc_cdecl_qsort be64_compare_signed(const void *, const void *);
1064
int __acc_cdecl_qsort le16_compare_signed(const void *, const void *);
1065
int __acc_cdecl_qsort le24_compare_signed(const void *, const void *);
1066
int __acc_cdecl_qsort le32_compare_signed(const void *, const void *);
1067
int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
1068
} // extern "C"
1069
1070
// <type_traits> upx_is_integral; see conf.h
1071
#define TT_UPX_IS_INTEGRAL(T)                                                                      \
1072
    template <>                                                                                    \
1073
    struct upx_is_integral<T> : public std::true_type {};                                          \
1074
    template <>                                                                                    \
1075
    struct upx_is_integral<const T> : public std::true_type {};                                    \
1076
    template <>                                                                                    \
1077
    struct upx_is_integral<volatile T> : public std::true_type {};                                 \
1078
    template <>                                                                                    \
1079
    struct upx_is_integral<const volatile T> : public std::true_type {}
1080
TT_UPX_IS_INTEGRAL(BE16);
1081
TT_UPX_IS_INTEGRAL(BE32);
1082
TT_UPX_IS_INTEGRAL(BE64);
1083
TT_UPX_IS_INTEGRAL(LE16);
1084
TT_UPX_IS_INTEGRAL(LE32);
1085
TT_UPX_IS_INTEGRAL(LE64);
1086
#undef TT_UPX_IS_INTEGRAL
1087
1088
// native types
1089
#if (ACC_ABI_BIG_ENDIAN)
1090
typedef BE16 NE16;
1091
typedef BE32 NE32;
1092
typedef BE64 NE64;
1093
#define ne16_compare        be16_compare
1094
#define ne32_compare        be32_compare
1095
#define ne64_compare        be64_compare
1096
#define ne16_compare_signed be16_compare_signed
1097
#define ne32_compare_signed be32_compare_signed
1098
#define ne64_compare_signed be64_compare_signed
1099
#else
1100
typedef LE16 NE16;
1101
typedef LE32 NE32;
1102
typedef LE64 NE64;
1103
#define ne16_compare        le16_compare
1104
0
#define ne32_compare        le32_compare
1105
#define ne64_compare        le64_compare
1106
#define ne16_compare_signed le16_compare_signed
1107
#define ne32_compare_signed le32_compare_signed
1108
#define ne64_compare_signed le64_compare_signed
1109
#endif
1110
1111
/*************************************************************************
1112
// Provide namespaces and classes to abstract endianness policies.
1113
//
1114
// CTP - Compile-Time Polymorphism (templates)
1115
// RTP - Run-Time Polymorphism (virtual functions)
1116
**************************************************************************/
1117
1118
// forward declarations
1119
namespace N_BELE_CTP {
1120
struct BEPolicy;
1121
struct LEPolicy;
1122
extern const BEPolicy be_policy;
1123
extern const LEPolicy le_policy;
1124
} // namespace N_BELE_CTP
1125
namespace N_BELE_RTP {
1126
struct AbstractPolicy;
1127
struct BEPolicy;
1128
struct LEPolicy;
1129
extern const BEPolicy be_policy;
1130
extern const LEPolicy le_policy;
1131
} // namespace N_BELE_RTP
1132
1133
// implementation
1134
namespace N_BELE_CTP {
1135
#define BELE_CTP 1
1136
#include "bele_policy.h"
1137
#undef BELE_CTP
1138
} // namespace N_BELE_CTP
1139
namespace N_BELE_RTP {
1140
#define BELE_RTP 1
1141
#include "bele_policy.h"
1142
#undef BELE_RTP
1143
} // namespace N_BELE_RTP
1144
1145
// util
1146
namespace N_BELE_CTP {
1147
16.5k
inline const N_BELE_RTP::AbstractPolicy *getRTP(const BEPolicy * /*dummy*/) noexcept {
1148
16.5k
    return &N_BELE_RTP::be_policy;
1149
16.5k
}
1150
39.7k
inline const N_BELE_RTP::AbstractPolicy *getRTP(const LEPolicy * /*dummy*/) noexcept {
1151
39.7k
    return &N_BELE_RTP::le_policy;
1152
39.7k
}
1153
} // namespace N_BELE_CTP
1154
1155
/* vim:set ts=4 sw=4 et: */