Skip to content

Commit b60d2b7

Browse files
committed
Merge #6: Fix UBSan "misaligned-pointer-use" warning on aarch64
1ac401e Fix UBSan "misaligned-pointer-use" warning on aarch64 (Hennadii Stepanov) Pull request description: As `data` type is a pointer to `uint8_t`, the access to the memory via the `(uint64_t *)data` pointer is misaligned. It can be an issue on ARM hardware. As suggested in https://en.cppreference.com/w/cpp/language/reinterpret_cast: > When it is needed to interpret the bytes of an object as a value of a different type, `std::memcpy` ... can be used. For more details, please refer to bitcoin/bitcoin#29178. Also: https://stackoverflow.com/questions/32062894/take-advantage-of-arm-unaligned-memory-access-while-writing-clean-c-code. ACKs for top commit: theuni: ACK 1ac401e. dergoegge: ACK 1ac401e Tree-SHA512: c459da5571dd607a742ed4d7d3aece264bbde83d30d62c500bf0708eadc3b101e505f7f5b6fd453650aea63703909d776db151b234845c414944913fecb5a862
2 parents 0bac72c + 1ac401e commit b60d2b7

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

src/crc32c_arm64.cc

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <cstddef>
1414
#include <cstdint>
15+
#include <cstring>
1516

1617
#include "./crc32c_internal.h"
1718
#ifdef CRC32C_HAVE_CONFIG_H
@@ -29,14 +30,14 @@
2930
// compute 8bytes for each segment parallelly
3031
#define CRC32C32BYTES(P, IND) \
3132
do { \
32-
crc1 = __crc32cd( \
33-
crc1, *((const uint64_t *)(P) + (SEGMENTBYTES / 8) * 1 + (IND))); \
34-
crc2 = __crc32cd( \
35-
crc2, *((const uint64_t *)(P) + (SEGMENTBYTES / 8) * 2 + (IND))); \
36-
crc3 = __crc32cd( \
37-
crc3, *((const uint64_t *)(P) + (SEGMENTBYTES / 8) * 3 + (IND))); \
38-
crc0 = __crc32cd( \
39-
crc0, *((const uint64_t *)(P) + (SEGMENTBYTES / 8) * 0 + (IND))); \
33+
std::memcpy(&d64, (P) + SEGMENTBYTES * 1 + (IND) * 8, sizeof(d64)); \
34+
crc1 = __crc32cd(crc1, d64); \
35+
std::memcpy(&d64, (P) + SEGMENTBYTES * 2 + (IND) * 8, sizeof(d64)); \
36+
crc2 = __crc32cd(crc2, d64); \
37+
std::memcpy(&d64, (P) + SEGMENTBYTES * 3 + (IND) * 8, sizeof(d64)); \
38+
crc3 = __crc32cd(crc3, d64); \
39+
std::memcpy(&d64, (P) + SEGMENTBYTES * 0 + (IND) * 8, sizeof(d64)); \
40+
crc0 = __crc32cd(crc0, d64); \
4041
} while (0);
4142

4243
// compute 8*8 bytes for each segment parallelly
@@ -68,6 +69,9 @@ uint32_t ExtendArm64(uint32_t crc, const uint8_t *data, size_t size) {
6869
int64_t length = size;
6970
uint32_t crc0, crc1, crc2, crc3;
7071
uint64_t t0, t1, t2;
72+
uint16_t d16;
73+
uint32_t d32;
74+
uint64_t d64;
7175

7276
// k0=CRC(x^(3*SEGMENTBYTES*8)), k1=CRC(x^(2*SEGMENTBYTES*8)),
7377
// k2=CRC(x^(SEGMENTBYTES*8))
@@ -88,7 +92,8 @@ uint32_t ExtendArm64(uint32_t crc, const uint8_t *data, size_t size) {
8892
t2 = (uint64_t)vmull_p64(crc2, k2);
8993
t1 = (uint64_t)vmull_p64(crc1, k1);
9094
t0 = (uint64_t)vmull_p64(crc0, k0);
91-
crc = __crc32cd(crc3, *(uint64_t *)data);
95+
std::memcpy(&d64, data, sizeof(d64));
96+
crc = __crc32cd(crc3, d64);
9297
data += sizeof(uint64_t);
9398
crc ^= __crc32cd(0, t2);
9499
crc ^= __crc32cd(0, t1);
@@ -98,18 +103,21 @@ uint32_t ExtendArm64(uint32_t crc, const uint8_t *data, size_t size) {
98103
}
99104

100105
while (length >= 8) {
101-
crc = __crc32cd(crc, *(uint64_t *)data);
106+
std::memcpy(&d64, data, sizeof(d64));
107+
crc = __crc32cd(crc, d64);
102108
data += 8;
103109
length -= 8;
104110
}
105111

106112
if (length & 4) {
107-
crc = __crc32cw(crc, *(uint32_t *)data);
113+
std::memcpy(&d32, data, sizeof(d32));
114+
crc = __crc32cw(crc, d32);
108115
data += 4;
109116
}
110117

111118
if (length & 2) {
112-
crc = __crc32ch(crc, *(uint16_t *)data);
119+
std::memcpy(&d16, data, sizeof(d16));
120+
crc = __crc32ch(crc, d16);
113121
data += 2;
114122
}
115123

0 commit comments

Comments
 (0)