summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/CRC.cpp
diff options
context:
space:
mode:
authorHans Wennborg <hans@chromium.org>2020-02-05 11:03:49 +0100
committerHans Wennborg <hans@chromium.org>2020-02-06 09:02:41 +0100
commitd0104a596199a41963dbba70338d9ff3c36b185a (patch)
tree02dda439aa032f7efe51abe9c029c992ba11a72a /llvm/lib/Support/CRC.cpp
parentc32d809e9cae8da7d3016b6cb30e2a2a9c9e2762 (diff)
downloadbcm5719-llvm-d0104a596199a41963dbba70338d9ff3c36b185a.tar.gz
bcm5719-llvm-d0104a596199a41963dbba70338d9ff3c36b185a.zip
Make llvm::crc32() work also for input sizes larger than 32 bits.
The problem was noticed by the Chrome OS toolchain folks (crbug.com/1048445) because llvm-objcopy --add-gnu-debuglink would insert the wrong checksum when processing a binary larger than 4 GB. That use case regressed in 1e1e3ba2526 when we started using llvm::crc32() in more places. Differential revision: https://reviews.llvm.org/D74039 (cherry picked from commit 6c4a8bc0a9f6a466d90d542bef66d69550c1b041)
Diffstat (limited to 'llvm/lib/Support/CRC.cpp')
-rw-r--r--llvm/lib/Support/CRC.cpp10
1 files changed, 9 insertions, 1 deletions
diff --git a/llvm/lib/Support/CRC.cpp b/llvm/lib/Support/CRC.cpp
index a3dba1a3aa1..2bc668beed3 100644
--- a/llvm/lib/Support/CRC.cpp
+++ b/llvm/lib/Support/CRC.cpp
@@ -85,7 +85,15 @@ uint32_t llvm::crc32(uint32_t CRC, ArrayRef<uint8_t> Data) {
#include <zlib.h>
uint32_t llvm::crc32(uint32_t CRC, ArrayRef<uint8_t> Data) {
- return ::crc32(CRC, (const Bytef *)Data.data(), Data.size());
+ // Zlib's crc32() only takes a 32-bit length, so we have to iterate for larger
+ // sizes. One could use crc32_z() instead, but that's a recent (2017) addition
+ // and may not be available on all systems.
+ do {
+ ArrayRef<uint8_t> Slice = Data.take_front(UINT32_MAX);
+ CRC = ::crc32(CRC, (const Bytef *)Slice.data(), (uInt)Slice.size());
+ Data = Data.drop_front(Slice.size());
+ } while (Data.size() > 0);
+ return CRC;
}
#endif
OpenPOWER on IntegriCloud