Coverage Report

Created: 2025-09-27 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/upx/src/bele.h
Line
Count
Source
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
7.57M
forceinline bele_constexpr unsigned get_ne16(const byte *p) noexcept {
113
7.57M
#if defined(upx_is_constant_evaluated)
114
7.57M
    if (upx_is_constant_evaluated())
115
0
        return upx::compile_time::get_ne16(p);
116
7.57M
    else
117
7.57M
#endif
118
7.57M
    {
119
7.57M
        upx_uint16_t v = 0;
120
7.57M
        upx_memcpy_inline(&v, p, sizeof(v));
121
7.57M
        return v;
122
7.57M
    }
123
7.57M
}
124
125
12.0M
forceinline bele_constexpr unsigned get_ne32(const byte *p) noexcept {
126
12.0M
#if defined(upx_is_constant_evaluated)
127
12.0M
    if (upx_is_constant_evaluated())
128
0
        return upx::compile_time::get_ne32(p);
129
12.0M
    else
130
12.0M
#endif
131
12.0M
    {
132
12.0M
        upx_uint32_t v = 0;
133
12.0M
        upx_memcpy_inline(&v, p, sizeof(v));
134
12.0M
        return v;
135
12.0M
    }
136
12.0M
}
137
138
7.22M
forceinline bele_constexpr upx_uint64_t get_ne64(const byte *p) noexcept {
139
7.22M
#if defined(upx_is_constant_evaluated)
140
7.22M
    if (upx_is_constant_evaluated())
141
0
        return upx::compile_time::get_ne64(p);
142
7.22M
    else
143
7.22M
#endif
144
7.22M
    {
145
7.22M
        upx_uint64_t v = 0;
146
7.22M
        upx_memcpy_inline(&v, p, sizeof(v));
147
7.22M
        return v;
148
7.22M
    }
149
7.22M
}
150
151
1.45M
forceinline bele_constexpr void set_ne16(byte *p, unsigned v) noexcept {
152
1.45M
#if defined(upx_is_constant_evaluated)
153
1.45M
    if (upx_is_constant_evaluated())
154
0
        upx::compile_time::set_ne16(p, upx_uint16_t(v & 0xffff));
155
1.45M
    else
156
1.45M
#endif
157
1.45M
    {
158
1.45M
        upx_uint16_t vv = upx_uint16_t(v & 0xffff);
159
1.45M
        upx_memcpy_inline(p, &vv, sizeof(vv));
160
1.45M
    }
161
1.45M
}
162
163
3.38M
forceinline bele_constexpr void set_ne32(byte *p, unsigned v) noexcept {
164
3.38M
#if defined(upx_is_constant_evaluated)
165
3.38M
    if (upx_is_constant_evaluated())
166
0
        upx::compile_time::set_ne32(p, v);
167
3.38M
    else
168
3.38M
#endif
169
3.38M
    {
170
3.38M
        upx_uint32_t vv = v;
171
3.38M
        upx_memcpy_inline(p, &vv, sizeof(vv));
172
3.38M
    }
173
3.38M
}
174
175
1.25M
forceinline bele_constexpr void set_ne64(byte *p, upx_uint64_t v) noexcept {
176
1.25M
#if defined(upx_is_constant_evaluated)
177
1.25M
    if (upx_is_constant_evaluated())
178
0
        upx::compile_time::set_ne64(p, v);
179
1.25M
    else
180
1.25M
#endif
181
1.25M
    {
182
1.25M
        upx_uint64_t vv = v;
183
1.25M
        upx_memcpy_inline(p, &vv, sizeof(vv));
184
1.25M
    }
185
1.25M
}
186
187
/*************************************************************************
188
// core - NE
189
**************************************************************************/
190
191
REQUIRE_XE16
192
307k
forceinline bele_constexpr unsigned get_ne16(const XE16 *p) noexcept {
193
307k
    return get_ne16(upx::ptr_static_cast<const byte *>(p));
194
307k
}
unsigned int get_ne16<void, void>(void const*)
Line
Count
Source
192
273k
forceinline bele_constexpr unsigned get_ne16(const XE16 *p) noexcept {
193
273k
    return get_ne16(upx::ptr_static_cast<const byte *>(p));
194
273k
}
unsigned int get_ne16<unsigned short, unsigned short>(unsigned short const*)
Line
Count
Source
192
11.4k
forceinline bele_constexpr unsigned get_ne16(const XE16 *p) noexcept {
193
11.4k
    return get_ne16(upx::ptr_static_cast<const byte *>(p));
194
11.4k
}
unsigned int get_ne16<LE16, LE16>(LE16 const*)
Line
Count
Source
192
22.0k
forceinline bele_constexpr unsigned get_ne16(const XE16 *p) noexcept {
193
22.0k
    return get_ne16(upx::ptr_static_cast<const byte *>(p));
194
22.0k
}
195
196
REQUIRE_XE32
197
953k
forceinline bele_constexpr unsigned get_ne32(const XE32 *p) noexcept {
198
953k
    return get_ne32(upx::ptr_static_cast<const byte *>(p));
199
953k
}
unsigned int get_ne32<void, void>(void const*)
Line
Count
Source
197
941k
forceinline bele_constexpr unsigned get_ne32(const XE32 *p) noexcept {
198
941k
    return get_ne32(upx::ptr_static_cast<const byte *>(p));
199
941k
}
unsigned int get_ne32<unsigned int, unsigned int>(unsigned int const*)
Line
Count
Source
197
11.4k
forceinline bele_constexpr unsigned get_ne32(const XE32 *p) noexcept {
198
11.4k
    return get_ne32(upx::ptr_static_cast<const byte *>(p));
199
11.4k
}
unsigned int get_ne32<LE32, LE32>(LE32 const*)
Line
Count
Source
197
788
forceinline bele_constexpr unsigned get_ne32(const XE32 *p) noexcept {
198
788
    return get_ne32(upx::ptr_static_cast<const byte *>(p));
199
788
}
Unexecuted instantiation: unsigned int get_ne32<char, char>(char const*)
200
201
REQUIRE_XE64
202
164k
forceinline bele_constexpr upx_uint64_t get_ne64(const XE64 *p) noexcept {
203
164k
    return get_ne64(upx::ptr_static_cast<const byte *>(p));
204
164k
}
unsigned long long get_ne64<void, void>(void const*)
Line
Count
Source
202
153k
forceinline bele_constexpr upx_uint64_t get_ne64(const XE64 *p) noexcept {
203
153k
    return get_ne64(upx::ptr_static_cast<const byte *>(p));
204
153k
}
unsigned long long get_ne64<unsigned long long, unsigned long long>(unsigned long long const*)
Line
Count
Source
202
11.4k
forceinline bele_constexpr upx_uint64_t get_ne64(const XE64 *p) noexcept {
203
11.4k
    return get_ne64(upx::ptr_static_cast<const byte *>(p));
204
11.4k
}
205
206
REQUIRE_XE16
207
11.4k
forceinline bele_constexpr void set_ne16(XE16 *p, unsigned v) noexcept {
208
11.4k
    set_ne16(upx::ptr_static_cast<byte *>(p), v);
209
11.4k
}
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
11.4k
forceinline bele_constexpr void set_ne16(XE16 *p, unsigned v) noexcept {
208
11.4k
    set_ne16(upx::ptr_static_cast<byte *>(p), v);
209
11.4k
}
Unexecuted instantiation: void set_ne16<LE16, LE16>(LE16*, unsigned int)
210
211
REQUIRE_XE32
212
34.2k
forceinline bele_constexpr void set_ne32(XE32 *p, unsigned v) noexcept {
213
34.2k
    set_ne32(upx::ptr_static_cast<byte *>(p), v);
214
34.2k
}
void set_ne32<void, void>(void*, unsigned int)
Line
Count
Source
212
22.8k
forceinline bele_constexpr void set_ne32(XE32 *p, unsigned v) noexcept {
213
22.8k
    set_ne32(upx::ptr_static_cast<byte *>(p), v);
214
22.8k
}
void set_ne32<unsigned int, unsigned int>(unsigned int*, unsigned int)
Line
Count
Source
212
11.4k
forceinline bele_constexpr void set_ne32(XE32 *p, unsigned v) noexcept {
213
11.4k
    set_ne32(upx::ptr_static_cast<byte *>(p), v);
214
11.4k
}
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
11.4k
forceinline bele_constexpr void set_ne64(XE64 *p, upx_uint64_t v) noexcept {
218
11.4k
    set_ne64(upx::ptr_static_cast<byte *>(p), v);
219
11.4k
}
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
11.4k
forceinline bele_constexpr void set_ne64(XE64 *p, upx_uint64_t v) noexcept {
218
11.4k
    set_ne64(upx::ptr_static_cast<byte *>(p), v);
219
11.4k
}
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
4.20M
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
4.20M
    return __builtin_bswap32(v << 16);
271
4.20M
#endif
272
4.20M
}
273
6.81M
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
6.81M
    return __builtin_bswap32(v);
278
6.81M
#endif
279
6.81M
}
280
4.16M
forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) noexcept { return __builtin_bswap64(v); }
281
282
#endif
283
284
4.79M
forceinline constexpr unsigned no_bswap16(unsigned v) noexcept {
285
    // mask is needed so that for all v: bswap16(bswap16(v)) == no_bswap16(v)
286
4.79M
    return v & 0xffff;
287
4.79M
}
288
7.88M
forceinline constexpr unsigned no_bswap32(unsigned v) noexcept { return v; }
289
4.29M
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
4.20M
#define ne16_to_be16(v) bswap16(v)
300
6.81M
#define ne32_to_be32(v) bswap32(v)
301
4.16M
#define ne64_to_be64(v) bswap64(v)
302
4.79M
#define ne16_to_le16(v) no_bswap16(v)
303
7.86M
#define ne32_to_le32(v) no_bswap32(v)
304
4.29M
#define ne64_to_le64(v) no_bswap64(v)
305
#endif
306
307
/*************************************************************************
308
// get/set 16/32/64
309
**************************************************************************/
310
311
REQUIRE_XE16
312
3.56M
inline bele_constexpr unsigned get_be16(const XE16 *p) noexcept {
313
3.56M
    return ne16_to_be16(get_ne16(p));
314
3.56M
}
unsigned int get_be16<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
312
3.49M
inline bele_constexpr unsigned get_be16(const XE16 *p) noexcept {
313
3.49M
    return ne16_to_be16(get_ne16(p));
314
3.49M
}
unsigned int get_be16<void, void>(void const*)
Line
Count
Source
312
72.4k
inline bele_constexpr unsigned get_be16(const XE16 *p) noexcept {
313
72.4k
    return ne16_to_be16(get_ne16(p));
314
72.4k
}
315
REQUIRE_XE32
316
6.06M
inline bele_constexpr unsigned get_be32(const XE32 *p) noexcept {
317
6.06M
    return ne32_to_be32(get_ne32(p));
318
6.06M
}
unsigned int get_be32<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
316
5.90M
inline bele_constexpr unsigned get_be32(const XE32 *p) noexcept {
317
5.90M
    return ne32_to_be32(get_ne32(p));
318
5.90M
}
unsigned int get_be32<void, void>(void const*)
Line
Count
Source
316
162k
inline bele_constexpr unsigned get_be32(const XE32 *p) noexcept {
317
162k
    return ne32_to_be32(get_ne32(p));
318
162k
}
319
REQUIRE_XE64
320
3.54M
inline bele_constexpr upx_uint64_t get_be64(const XE64 *p) noexcept {
321
3.54M
    return ne64_to_be64(get_ne64(p));
322
3.54M
}
unsigned long long get_be64<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
320
3.49M
inline bele_constexpr upx_uint64_t get_be64(const XE64 *p) noexcept {
321
3.49M
    return ne64_to_be64(get_ne64(p));
322
3.49M
}
unsigned long long get_be64<void, void>(void const*)
Line
Count
Source
320
44.8k
inline bele_constexpr upx_uint64_t get_be64(const XE64 *p) noexcept {
321
44.8k
    return ne64_to_be64(get_ne64(p));
322
44.8k
}
323
REQUIRE_XE16
324
3.99M
inline bele_constexpr unsigned get_le16(const XE16 *p) noexcept {
325
3.99M
    return ne16_to_le16(get_ne16(p));
326
3.99M
}
unsigned int get_le16<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
324
3.77M
inline bele_constexpr unsigned get_le16(const XE16 *p) noexcept {
325
3.77M
    return ne16_to_le16(get_ne16(p));
326
3.77M
}
unsigned int get_le16<void, void>(void const*)
Line
Count
Source
324
201k
inline bele_constexpr unsigned get_le16(const XE16 *p) noexcept {
325
201k
    return ne16_to_le16(get_ne16(p));
326
201k
}
unsigned int get_le16<LE16, LE16>(LE16 const*)
Line
Count
Source
324
22.0k
inline bele_constexpr unsigned get_le16(const XE16 *p) noexcept {
325
22.0k
    return ne16_to_le16(get_ne16(p));
326
22.0k
}
327
REQUIRE_XE32
328
4.81M
inline bele_constexpr unsigned get_le32(const XE32 *p) noexcept {
329
4.81M
    return ne32_to_le32(get_ne32(p));
330
4.81M
}
unsigned int get_le32<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
328
4.30M
inline bele_constexpr unsigned get_le32(const XE32 *p) noexcept {
329
4.30M
    return ne32_to_le32(get_ne32(p));
330
4.30M
}
unsigned int get_le32<void, void>(void const*)
Line
Count
Source
328
511k
inline bele_constexpr unsigned get_le32(const XE32 *p) noexcept {
329
511k
    return ne32_to_le32(get_ne32(p));
330
511k
}
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
788
inline bele_constexpr unsigned get_le32(const XE32 *p) noexcept {
329
788
    return ne32_to_le32(get_ne32(p));
330
788
}
Unexecuted instantiation: unsigned int get_le32<char, char>(char const*)
331
REQUIRE_XE64
332
3.66M
inline bele_constexpr upx_uint64_t get_le64(const XE64 *p) noexcept {
333
3.66M
    return ne64_to_le64(get_ne64(p));
334
3.66M
}
unsigned long long get_le64<unsigned char, unsigned char>(unsigned char const*)
Line
Count
Source
332
3.56M
inline bele_constexpr upx_uint64_t get_le64(const XE64 *p) noexcept {
333
3.56M
    return ne64_to_le64(get_ne64(p));
334
3.56M
}
unsigned long long get_le64<void, void>(void const*)
Line
Count
Source
332
108k
inline bele_constexpr upx_uint64_t get_le64(const XE64 *p) noexcept {
333
108k
    return ne64_to_le64(get_ne64(p));
334
108k
}
335
336
REQUIRE_XE16
337
639k
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
639k
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
755k
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
755k
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
621k
inline bele_constexpr void set_be64(XE64 *p, upx_uint64_t v) noexcept {
342
621k
    set_ne64(p, ne64_to_be64(v));
343
621k
}
void set_be64<unsigned char, unsigned char>(unsigned char*, unsigned long long)
Line
Count
Source
341
621k
inline bele_constexpr void set_be64(XE64 *p, upx_uint64_t v) noexcept {
342
621k
    set_ne64(p, ne64_to_be64(v));
343
621k
}
Unexecuted instantiation: void set_be64<void, void>(void*, unsigned long long)
344
REQUIRE_XE16
345
803k
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
803k
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
1.72M
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
1.72M
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
621k
inline bele_constexpr void set_le64(XE64 *p, upx_uint64_t v) noexcept {
350
621k
    set_ne64(p, ne64_to_le64(v));
351
621k
}
void set_le64<unsigned char, unsigned char>(unsigned char*, unsigned long long)
Line
Count
Source
349
621k
inline bele_constexpr void set_le64(XE64 *p, upx_uint64_t v) noexcept {
350
621k
    set_ne64(p, ne64_to_le64(v));
351
621k
}
Unexecuted instantiation: void set_le64<void, void>(void*, unsigned long long)
352
353
/*************************************************************************
354
// get/set 24/26
355
**************************************************************************/
356
357
45.4k
inline constexpr unsigned get_be24(const byte *p) noexcept {
358
45.4k
    return upx::compile_time::get_be24(p);
359
45.4k
}
360
90.2k
inline constexpr unsigned get_le24(const byte *p) noexcept {
361
90.2k
    return upx::compile_time::get_le24(p);
362
90.2k
}
363
34.0k
inline constexpr void set_be24(byte *p, unsigned v) noexcept { upx::compile_time::set_be24(p, v); }
364
78.6k
inline constexpr void set_le24(byte *p, unsigned v) noexcept { upx::compile_time::set_le24(p, v); }
365
366
REQUIRE_XE24
367
11.4k
forceinline bele_constexpr unsigned get_be24(const XE24 *p) noexcept {
368
11.4k
    return get_be24(upx::ptr_static_cast<const byte *>(p));
369
11.4k
}
370
REQUIRE_XE24
371
11.4k
forceinline bele_constexpr unsigned get_le24(const XE24 *p) noexcept {
372
11.4k
    return get_le24(upx::ptr_static_cast<const byte *>(p));
373
11.4k
}
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
446k
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
34.2k
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
411k
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
434k
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
434k
    set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) |
400
434k
                    (ne32_to_le32(v) & ne32_to_le32(0x03ffffff)));
401
434k
}
void set_le26<void, void>(void*, unsigned int)
Line
Count
Source
395
22.8k
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
22.8k
    set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) |
400
22.8k
                    (ne32_to_le32(v) & ne32_to_le32(0x03ffffff)));
401
22.8k
}
void set_le26<unsigned char, unsigned char>(unsigned char*, unsigned int)
Line
Count
Source
395
411k
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
411k
    set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) |
400
411k
                    (ne32_to_le32(v) & ne32_to_le32(0x03ffffff)));
401
411k
}
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
68.5k
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
68.5k
    return ACC_ICAST(int, v << (32 - bits)) >> (32 - bits);
421
68.5k
#endif
422
68.5k
}
423
424
34.2k
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
34.2k
    return ACC_ICAST(upx_int64_t, v << (64 - bits)) >> (64 - bits);
430
34.2k
#endif
431
34.2k
}
432
433
REQUIRE_XE16
434
22.8k
inline bele_constexpr int get_be16_signed(const XE16 *p) noexcept {
435
22.8k
    unsigned v = get_be16(p);
436
22.8k
    return sign_extend32(v, 16);
437
22.8k
}
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
22.8k
inline bele_constexpr int get_be16_signed(const XE16 *p) noexcept {
435
22.8k
    unsigned v = get_be16(p);
436
22.8k
    return sign_extend32(v, 16);
437
22.8k
}
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
22.8k
inline bele_constexpr int get_be32_signed(const XE32 *p) noexcept {
447
22.8k
    unsigned v = get_be32(p);
448
22.8k
    return sign_extend32(v, 32);
449
22.8k
}
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
22.8k
inline bele_constexpr int get_be32_signed(const XE32 *p) noexcept {
447
22.8k
    unsigned v = get_be32(p);
448
22.8k
    return sign_extend32(v, 32);
449
22.8k
}
450
451
REQUIRE_XE64
452
22.8k
inline bele_constexpr upx_int64_t get_be64_signed(const XE64 *p) noexcept {
453
22.8k
    upx_uint64_t v = get_be64(p);
454
22.8k
    return sign_extend64(v, 64);
455
22.8k
}
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
22.8k
inline bele_constexpr upx_int64_t get_be64_signed(const XE64 *p) noexcept {
453
22.8k
    upx_uint64_t v = get_be64(p);
454
22.8k
    return sign_extend64(v, 64);
455
22.8k
}
456
457
REQUIRE_XE16
458
11.4k
inline bele_constexpr int get_le16_signed(const XE16 *p) noexcept {
459
11.4k
    unsigned v = get_le16(p);
460
11.4k
    return sign_extend32(v, 16);
461
11.4k
}
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
11.4k
inline bele_constexpr int get_le16_signed(const XE16 *p) noexcept {
459
11.4k
    unsigned v = get_le16(p);
460
11.4k
    return sign_extend32(v, 16);
461
11.4k
}
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
11.4k
inline bele_constexpr int get_le32_signed(const XE32 *p) noexcept {
471
11.4k
    unsigned v = get_le32(p);
472
11.4k
    return sign_extend32(v, 32);
473
11.4k
}
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
11.4k
inline bele_constexpr int get_le32_signed(const XE32 *p) noexcept {
471
11.4k
    unsigned v = get_le32(p);
472
11.4k
    return sign_extend32(v, 32);
473
11.4k
}
474
475
REQUIRE_XE64
476
11.4k
inline bele_constexpr upx_int64_t get_le64_signed(const XE64 *p) noexcept {
477
11.4k
    upx_uint64_t v = get_le64(p);
478
11.4k
    return sign_extend64(v, 64);
479
11.4k
}
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
11.4k
inline bele_constexpr upx_int64_t get_le64_signed(const XE64 *p) noexcept {
477
11.4k
    upx_uint64_t v = get_le64(p);
478
11.4k
    return sign_extend64(v, 64);
479
11.4k
}
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
3.25M
    forceinline bele_constexpr operator unsigned() const noexcept { return get_be16(d); }
501
502
388k
    forceinline bele_constexpr BE16 &operator=(unsigned v) noexcept {
503
388k
        set_be16(d, v);
504
388k
        return *this;
505
388k
    }
506
34.2k
    BE16 &operator+=(unsigned v) noexcept {
507
34.2k
        set_be16(d, get_be16(d) + v);
508
34.2k
        return *this;
509
34.2k
    }
510
57.1k
    BE16 &operator-=(unsigned v) noexcept {
511
57.1k
        set_be16(d, get_be16(d) - v);
512
57.1k
        return *this;
513
57.1k
    }
514
22.8k
    BE16 &operator*=(unsigned v) noexcept {
515
22.8k
        set_be16(d, get_be16(d) * v);
516
22.8k
        return *this;
517
22.8k
    }
518
22.8k
    BE16 &operator/=(unsigned v) noexcept {
519
22.8k
        set_be16(d, get_be16(d) / v);
520
22.8k
        return *this;
521
22.8k
    }
522
11.4k
    BE16 &operator&=(unsigned v) noexcept {
523
11.4k
        set_be16(d, get_be16(d) & v);
524
11.4k
        return *this;
525
11.4k
    }
526
11.4k
    BE16 &operator|=(unsigned v) noexcept {
527
11.4k
        set_be16(d, get_be16(d) | v);
528
11.4k
        return *this;
529
11.4k
    }
530
11.4k
    BE16 &operator^=(unsigned v) noexcept {
531
11.4k
        set_be16(d, get_be16(d) ^ v);
532
11.4k
        return *this;
533
11.4k
    }
534
11.4k
    BE16 &operator<<=(unsigned v) noexcept {
535
11.4k
        set_be16(d, get_be16(d) << v);
536
11.4k
        return *this;
537
11.4k
    }
538
11.4k
    BE16 &operator>>=(unsigned v) noexcept {
539
11.4k
        set_be16(d, get_be16(d) >> v);
540
11.4k
        return *this;
541
11.4k
    }
542
543
274k
    bele_constexpr bool operator==(const BE16 &x) const noexcept {
544
274k
#if defined(upx_is_constant_evaluated)
545
274k
        if (upx_is_constant_evaluated())
546
0
            return upx::compile_time::mem_eq(d, x.d, sizeof(d));
547
274k
        else
548
274k
#endif
549
274k
            return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
550
274k
    }
551
251k
    bele_constexpr bool operator<(const BE16 &x) const noexcept {
552
251k
        return unsigned(*this) < unsigned(x);
553
251k
    }
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
3.27M
    forceinline bele_constexpr operator unsigned() const noexcept { return get_be32(d); }
568
569
399k
    forceinline bele_constexpr BE32 &operator=(unsigned v) noexcept {
570
399k
        set_be32(d, v);
571
399k
        return *this;
572
399k
    }
573
34.2k
    BE32 &operator+=(unsigned v) noexcept {
574
34.2k
        set_be32(d, get_be32(d) + v);
575
34.2k
        return *this;
576
34.2k
    }
577
68.5k
    BE32 &operator-=(unsigned v) noexcept {
578
68.5k
        set_be32(d, get_be32(d) - v);
579
68.5k
        return *this;
580
68.5k
    }
581
22.8k
    BE32 &operator*=(unsigned v) noexcept {
582
22.8k
        set_be32(d, get_be32(d) * v);
583
22.8k
        return *this;
584
22.8k
    }
585
22.8k
    BE32 &operator/=(unsigned v) noexcept {
586
22.8k
        set_be32(d, get_be32(d) / v);
587
22.8k
        return *this;
588
22.8k
    }
589
11.4k
    BE32 &operator&=(unsigned v) noexcept {
590
11.4k
        set_be32(d, get_be32(d) & v);
591
11.4k
        return *this;
592
11.4k
    }
593
11.4k
    BE32 &operator|=(unsigned v) noexcept {
594
11.4k
        set_be32(d, get_be32(d) | v);
595
11.4k
        return *this;
596
11.4k
    }
597
11.4k
    BE32 &operator^=(unsigned v) noexcept {
598
11.4k
        set_be32(d, get_be32(d) ^ v);
599
11.4k
        return *this;
600
11.4k
    }
601
11.4k
    BE32 &operator<<=(unsigned v) noexcept {
602
11.4k
        set_be32(d, get_be32(d) << v);
603
11.4k
        return *this;
604
11.4k
    }
605
11.4k
    BE32 &operator>>=(unsigned v) noexcept {
606
11.4k
        set_be32(d, get_be32(d) >> v);
607
11.4k
        return *this;
608
11.4k
    }
609
610
274k
    bele_constexpr bool operator==(const BE32 &x) const noexcept {
611
274k
#if defined(upx_is_constant_evaluated)
612
274k
        if (upx_is_constant_evaluated())
613
0
            return upx::compile_time::mem_eq(d, x.d, sizeof(d));
614
274k
        else
615
274k
#endif
616
274k
            return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
617
274k
    }
618
251k
    bele_constexpr bool operator<(const BE32 &x) const noexcept {
619
251k
        return unsigned(*this) < unsigned(x);
620
251k
    }
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
3.25M
    forceinline bele_constexpr operator upx_uint64_t() const noexcept { return get_be64(d); }
635
636
399k
    forceinline bele_constexpr BE64 &operator=(upx_uint64_t v) noexcept {
637
399k
        set_be64(d, v);
638
399k
        return *this;
639
399k
    }
640
34.2k
    BE64 &operator+=(upx_uint64_t v) noexcept {
641
34.2k
        set_be64(d, get_be64(d) + v);
642
34.2k
        return *this;
643
34.2k
    }
644
68.5k
    BE64 &operator-=(upx_uint64_t v) noexcept {
645
68.5k
        set_be64(d, get_be64(d) - v);
646
68.5k
        return *this;
647
68.5k
    }
648
22.8k
    BE64 &operator*=(upx_uint64_t v) noexcept {
649
22.8k
        set_be64(d, get_be64(d) * v);
650
22.8k
        return *this;
651
22.8k
    }
652
22.8k
    BE64 &operator/=(upx_uint64_t v) noexcept {
653
22.8k
        set_be64(d, get_be64(d) / v);
654
22.8k
        return *this;
655
22.8k
    }
656
11.4k
    BE64 &operator&=(upx_uint64_t v) noexcept {
657
11.4k
        set_be64(d, get_be64(d) & v);
658
11.4k
        return *this;
659
11.4k
    }
660
11.4k
    BE64 &operator|=(upx_uint64_t v) noexcept {
661
11.4k
        set_be64(d, get_be64(d) | v);
662
11.4k
        return *this;
663
11.4k
    }
664
11.4k
    BE64 &operator^=(upx_uint64_t v) noexcept {
665
11.4k
        set_be64(d, get_be64(d) ^ v);
666
11.4k
        return *this;
667
11.4k
    }
668
11.4k
    BE64 &operator<<=(unsigned v) noexcept {
669
11.4k
        set_be64(d, get_be64(d) << v);
670
11.4k
        return *this;
671
11.4k
    }
672
11.4k
    BE64 &operator>>=(unsigned v) noexcept {
673
11.4k
        set_be64(d, get_be64(d) >> v);
674
11.4k
        return *this;
675
11.4k
    }
676
677
274k
    bele_constexpr bool operator==(const BE64 &x) const noexcept {
678
274k
#if defined(upx_is_constant_evaluated)
679
274k
        if (upx_is_constant_evaluated())
680
0
            return upx::compile_time::mem_eq(d, x.d, sizeof(d));
681
274k
        else
682
274k
#endif
683
274k
            return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
684
274k
    }
685
251k
    bele_constexpr bool operator<(const BE64 &x) const noexcept {
686
251k
        return upx_uint64_t(*this) < upx_uint64_t(x);
687
251k
    }
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
3.31M
    forceinline bele_constexpr operator unsigned() const noexcept { return get_le16(d); }
702
703
407k
    forceinline bele_constexpr LE16 &operator=(unsigned v) noexcept {
704
407k
        set_le16(d, v);
705
407k
        return *this;
706
407k
    }
707
34.2k
    LE16 &operator+=(unsigned v) noexcept {
708
34.2k
        set_le16(d, get_le16(d) + v);
709
34.2k
        return *this;
710
34.2k
    }
711
57.1k
    LE16 &operator-=(unsigned v) noexcept {
712
57.1k
        set_le16(d, get_le16(d) - v);
713
57.1k
        return *this;
714
57.1k
    }
715
22.8k
    LE16 &operator*=(unsigned v) noexcept {
716
22.8k
        set_le16(d, get_le16(d) * v);
717
22.8k
        return *this;
718
22.8k
    }
719
22.8k
    LE16 &operator/=(unsigned v) noexcept {
720
22.8k
        set_le16(d, get_le16(d) / v);
721
22.8k
        return *this;
722
22.8k
    }
723
11.4k
    LE16 &operator&=(unsigned v) noexcept {
724
11.4k
        set_le16(d, get_le16(d) & v);
725
11.4k
        return *this;
726
11.4k
    }
727
11.4k
    LE16 &operator|=(unsigned v) noexcept {
728
11.4k
        set_le16(d, get_le16(d) | v);
729
11.4k
        return *this;
730
11.4k
    }
731
11.4k
    LE16 &operator^=(unsigned v) noexcept {
732
11.4k
        set_le16(d, get_le16(d) ^ v);
733
11.4k
        return *this;
734
11.4k
    }
735
11.4k
    LE16 &operator<<=(unsigned v) noexcept {
736
11.4k
        set_le16(d, get_le16(d) << v);
737
11.4k
        return *this;
738
11.4k
    }
739
11.4k
    LE16 &operator>>=(unsigned v) noexcept {
740
11.4k
        set_le16(d, get_le16(d) >> v);
741
11.4k
        return *this;
742
11.4k
    }
743
744
274k
    bele_constexpr bool operator==(const LE16 &x) const noexcept {
745
274k
#if defined(upx_is_constant_evaluated)
746
274k
        if (upx_is_constant_evaluated())
747
0
            return upx::compile_time::mem_eq(d, x.d, sizeof(d));
748
274k
        else
749
274k
#endif
750
274k
            return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
751
274k
    }
752
251k
    bele_constexpr bool operator<(const LE16 &x) const noexcept {
753
251k
        return unsigned(*this) < unsigned(x);
754
251k
    }
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
3.45M
    forceinline bele_constexpr operator unsigned() const noexcept { return get_le32(d); }
769
770
419k
    forceinline bele_constexpr LE32 &operator=(unsigned v) noexcept {
771
419k
        set_le32(d, v);
772
419k
        return *this;
773
419k
    }
774
53.0k
    LE32 &operator+=(unsigned v) noexcept {
775
53.0k
        set_le32(d, get_le32(d) + v);
776
53.0k
        return *this;
777
53.0k
    }
778
68.5k
    LE32 &operator-=(unsigned v) noexcept {
779
68.5k
        set_le32(d, get_le32(d) - v);
780
68.5k
        return *this;
781
68.5k
    }
782
22.8k
    LE32 &operator*=(unsigned v) noexcept {
783
22.8k
        set_le32(d, get_le32(d) * v);
784
22.8k
        return *this;
785
22.8k
    }
786
22.8k
    LE32 &operator/=(unsigned v) noexcept {
787
22.8k
        set_le32(d, get_le32(d) / v);
788
22.8k
        return *this;
789
22.8k
    }
790
11.4k
    LE32 &operator&=(unsigned v) noexcept {
791
11.4k
        set_le32(d, get_le32(d) & v);
792
11.4k
        return *this;
793
11.4k
    }
794
11.4k
    LE32 &operator|=(unsigned v) noexcept {
795
11.4k
        set_le32(d, get_le32(d) | v);
796
11.4k
        return *this;
797
11.4k
    }
798
11.4k
    LE32 &operator^=(unsigned v) noexcept {
799
11.4k
        set_le32(d, get_le32(d) ^ v);
800
11.4k
        return *this;
801
11.4k
    }
802
11.4k
    LE32 &operator<<=(unsigned v) noexcept {
803
11.4k
        set_le32(d, get_le32(d) << v);
804
11.4k
        return *this;
805
11.4k
    }
806
11.4k
    LE32 &operator>>=(unsigned v) noexcept {
807
11.4k
        set_le32(d, get_le32(d) >> v);
808
11.4k
        return *this;
809
11.4k
    }
810
811
274k
    bele_constexpr bool operator==(const LE32 &x) const noexcept {
812
274k
#if defined(upx_is_constant_evaluated)
813
274k
        if (upx_is_constant_evaluated())
814
0
            return upx::compile_time::mem_eq(d, x.d, sizeof(d));
815
274k
        else
816
274k
#endif
817
274k
            return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
818
274k
    }
819
251k
    bele_constexpr bool operator<(const LE32 &x) const noexcept {
820
251k
        return unsigned(*this) < unsigned(x);
821
251k
    }
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
3.32M
    forceinline bele_constexpr operator upx_uint64_t() const noexcept { return get_le64(d); }
836
837
399k
    forceinline bele_constexpr LE64 &operator=(upx_uint64_t v) noexcept {
838
399k
        set_le64(d, v);
839
399k
        return *this;
840
399k
    }
841
34.2k
    LE64 &operator+=(upx_uint64_t v) noexcept {
842
34.2k
        set_le64(d, get_le64(d) + v);
843
34.2k
        return *this;
844
34.2k
    }
845
68.5k
    LE64 &operator-=(upx_uint64_t v) noexcept {
846
68.5k
        set_le64(d, get_le64(d) - v);
847
68.5k
        return *this;
848
68.5k
    }
849
22.8k
    LE64 &operator*=(upx_uint64_t v) noexcept {
850
22.8k
        set_le64(d, get_le64(d) * v);
851
22.8k
        return *this;
852
22.8k
    }
853
22.8k
    LE64 &operator/=(upx_uint64_t v) noexcept {
854
22.8k
        set_le64(d, get_le64(d) / v);
855
22.8k
        return *this;
856
22.8k
    }
857
11.4k
    LE64 &operator&=(upx_uint64_t v) noexcept {
858
11.4k
        set_le64(d, get_le64(d) & v);
859
11.4k
        return *this;
860
11.4k
    }
861
11.4k
    LE64 &operator|=(upx_uint64_t v) noexcept {
862
11.4k
        set_le64(d, get_le64(d) | v);
863
11.4k
        return *this;
864
11.4k
    }
865
11.4k
    LE64 &operator^=(upx_uint64_t v) noexcept {
866
11.4k
        set_le64(d, get_le64(d) ^ v);
867
11.4k
        return *this;
868
11.4k
    }
869
11.4k
    LE64 &operator<<=(unsigned v) noexcept {
870
11.4k
        set_le64(d, get_le64(d) << v);
871
11.4k
        return *this;
872
11.4k
    }
873
11.4k
    LE64 &operator>>=(unsigned v) noexcept {
874
11.4k
        set_le64(d, get_le64(d) >> v);
875
11.4k
        return *this;
876
11.4k
    }
877
878
274k
    bele_constexpr bool operator==(const LE64 &x) const noexcept {
879
274k
#if defined(upx_is_constant_evaluated)
880
274k
        if (upx_is_constant_evaluated())
881
0
            return upx::compile_time::mem_eq(d, x.d, sizeof(d));
882
274k
        else
883
274k
#endif
884
274k
            return upx_memcmp_inline(d, x.d, sizeof(d)) == 0;
885
274k
    }
886
251k
    bele_constexpr bool operator<(const LE64 &x) const noexcept {
887
251k
        return upx_uint64_t(*this) < upx_uint64_t(x);
888
251k
    }
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
908
inline bele_constexpr T *operator+(T *ptr, const BE32 &v) noexcept {
905
908
    return ptr + unsigned(v);
906
908
}
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.38k
inline bele_constexpr T *operator+(T *ptr, const LE32 &v) noexcept {
921
2.38k
    return ptr + unsigned(v);
922
2.38k
}
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.38k
inline bele_constexpr T *operator+(T *ptr, const LE32 &v) noexcept {
921
2.38k
    return ptr + unsigned(v);
922
2.38k
}
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
60
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
91.3k
inline bele_constexpr T min(const T &a, const BE16 &b) noexcept { return min(a, T(b)); }
993
REQUIRE_UINT32
994
91.3k
inline bele_constexpr T min(const BE16 &a, const T &b) noexcept { return min(T(a), b); }
995
REQUIRE_UINT32
996
91.3k
inline bele_constexpr T min(const T &a, const BE32 &b) noexcept { return min(a, T(b)); }
997
REQUIRE_UINT32
998
91.3k
inline bele_constexpr T min(const BE32 &a, const T &b) noexcept { return min(T(a), b); }
999
REQUIRE_UINT64
1000
91.3k
inline bele_constexpr T min(const T &a, const BE64 &b) noexcept { return min(a, T(b)); }
1001
REQUIRE_UINT64
1002
91.3k
inline bele_constexpr T min(const BE64 &a, const T &b) noexcept { return min(T(a), b); }
1003
REQUIRE_UINT32
1004
91.3k
inline bele_constexpr T min(const T &a, const LE16 &b) noexcept { return min(a, T(b)); }
1005
REQUIRE_UINT32
1006
91.3k
inline bele_constexpr T min(const LE16 &a, const T &b) noexcept { return min(T(a), b); }
1007
REQUIRE_UINT32
1008
91.3k
inline bele_constexpr T min(const T &a, const LE32 &b) noexcept { return min(a, T(b)); }
1009
REQUIRE_UINT32
1010
91.3k
inline bele_constexpr T min(const LE32 &a, const T &b) noexcept { return min(T(a), b); }
1011
REQUIRE_UINT64
1012
91.3k
inline bele_constexpr T min(const T &a, const LE64 &b) noexcept { return min(a, T(b)); }
1013
REQUIRE_UINT64
1014
91.3k
inline bele_constexpr T min(const LE64 &a, const T &b) noexcept { return min(T(a), b); }
1015
1016
REQUIRE_UINT32
1017
91.3k
inline bele_constexpr T max(const T &a, const BE16 &b) noexcept { return max(a, T(b)); }
1018
REQUIRE_UINT32
1019
91.3k
inline bele_constexpr T max(const BE16 &a, const T &b) noexcept { return max(T(a), b); }
1020
REQUIRE_UINT32
1021
91.3k
inline bele_constexpr T max(const T &a, const BE32 &b) noexcept { return max(a, T(b)); }
1022
REQUIRE_UINT32
1023
91.3k
inline bele_constexpr T max(const BE32 &a, const T &b) noexcept { return max(T(a), b); }
1024
REQUIRE_UINT64
1025
91.3k
inline bele_constexpr T max(const T &a, const BE64 &b) noexcept { return max(a, T(b)); }
1026
REQUIRE_UINT64
1027
91.3k
inline bele_constexpr T max(const BE64 &a, const T &b) noexcept { return max(T(a), b); }
1028
REQUIRE_UINT32
1029
91.3k
inline bele_constexpr T max(const T &a, const LE16 &b) noexcept { return max(a, T(b)); }
1030
REQUIRE_UINT32
1031
91.3k
inline bele_constexpr T max(const LE16 &a, const T &b) noexcept { return max(T(a), b); }
1032
REQUIRE_UINT32
1033
91.3k
inline bele_constexpr T max(const T &a, const LE32 &b) noexcept { return max(a, T(b)); }
1034
REQUIRE_UINT32
1035
91.3k
inline bele_constexpr T max(const LE32 &a, const T &b) noexcept { return max(T(a), b); }
1036
REQUIRE_UINT64
1037
91.3k
inline bele_constexpr T max(const T &a, const LE64 &b) noexcept { return max(a, T(b)); }
1038
REQUIRE_UINT64
1039
91.3k
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
12.2k
inline const N_BELE_RTP::AbstractPolicy *getRTP(const BEPolicy * /*dummy*/) noexcept {
1148
12.2k
    return &N_BELE_RTP::be_policy;
1149
12.2k
}
1150
29.5k
inline const N_BELE_RTP::AbstractPolicy *getRTP(const LEPolicy * /*dummy*/) noexcept {
1151
29.5k
    return &N_BELE_RTP::le_policy;
1152
29.5k
}
1153
} // namespace N_BELE_CTP
1154
1155
/* vim:set ts=4 sw=4 et: */