Skip to content

Commit ad69bd6

Browse files
committed
[Support] Add zlib independent CRC32
Differential revision: https://reviews.llvm.org/D59816 llvm-svn: 357901
1 parent eb1a156 commit ad69bd6

File tree

6 files changed

+126
-1
lines changed

6 files changed

+126
-1
lines changed

llvm/include/llvm/Support/CRC.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===-- llvm/Support/CRC.h - Cyclic Redundancy Check-------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file contains basic functions for calculating Cyclic Redundancy Check
10+
// or CRC.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_SUPPORT_CRC_H
15+
#define LLVM_SUPPORT_CRC_H
16+
17+
#include "llvm/ADT/StringRef.h"
18+
#include "llvm/Support/DataTypes.h"
19+
20+
namespace llvm {
21+
/// zlib independent CRC32 calculation.
22+
uint32_t crc32(uint32_t CRC, StringRef S);
23+
} // end namespace llvm
24+
25+
#endif

llvm/lib/DebugInfo/Symbolize/Symbolize.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "llvm/Object/COFF.h"
2424
#include "llvm/Object/MachO.h"
2525
#include "llvm/Object/MachOUniversal.h"
26+
#include "llvm/Support/CRC.h"
2627
#include "llvm/Support/Casting.h"
2728
#include "llvm/Support/Compression.h"
2829
#include "llvm/Support/DataExtractor.h"
@@ -163,7 +164,7 @@ bool checkFileCRC(StringRef Path, uint32_t CRCHash) {
163164
MemoryBuffer::getFileOrSTDIN(Path);
164165
if (!MB)
165166
return false;
166-
return !zlib::isAvailable() || CRCHash == zlib::crc32(MB.get()->getBuffer());
167+
return CRCHash == crc32(0, MB.get()->getBuffer());
167168
}
168169

169170
bool findDebugBinary(const std::string &OrigPath,

llvm/lib/Support/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ add_llvm_library(LLVMSupport
7676
CodeGenCoverage.cpp
7777
CommandLine.cpp
7878
Compression.cpp
79+
CRC.cpp
7980
ConvertUTF.cpp
8081
ConvertUTFWrapper.cpp
8182
CrashRecoveryContext.cpp

llvm/lib/Support/CRC.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//===--- CRC.cpp - Cyclic Redundancy Check implementation -----------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file implements llvm::crc32 function.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "llvm/Support/CRC.h"
14+
#include "llvm/Config/config.h"
15+
#include "llvm/ADT/StringRef.h"
16+
#include "llvm/Support/Threading.h"
17+
#include <array>
18+
19+
using namespace llvm;
20+
21+
#if LLVM_ENABLE_ZLIB == 0 || !HAVE_ZLIB_H
22+
using CRC32Table = std::array<uint32_t, 256>;
23+
24+
static void initCRC32Table(CRC32Table &Tbl) {
25+
auto Shuffle = [](uint32_t V) {
26+
return (V & 1) ? (V >> 1) ^ 0xEDB88320U : V >> 1;
27+
};
28+
29+
for (size_t I = 0; I < Tbl.size(); ++I) {
30+
uint32_t V = Shuffle(I);
31+
V = Shuffle(V);
32+
V = Shuffle(V);
33+
V = Shuffle(V);
34+
V = Shuffle(V);
35+
V = Shuffle(V);
36+
V = Shuffle(V);
37+
Tbl[I] = Shuffle(V);
38+
}
39+
}
40+
41+
uint32_t llvm::crc32(uint32_t CRC, StringRef S) {
42+
static llvm::once_flag InitFlag;
43+
static CRC32Table Tbl;
44+
llvm::call_once(InitFlag, initCRC32Table, Tbl);
45+
46+
const uint8_t *P = reinterpret_cast<const uint8_t *>(S.data());
47+
size_t Len = S.size();
48+
CRC ^= 0xFFFFFFFFU;
49+
for (; Len >= 8; Len -= 8) {
50+
CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
51+
CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
52+
CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
53+
CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
54+
CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
55+
CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
56+
CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
57+
CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
58+
}
59+
while (Len--)
60+
CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8);
61+
return CRC ^ 0xFFFFFFFFU;
62+
}
63+
#else
64+
#include <zlib.h>
65+
uint32_t llvm::crc32(uint32_t CRC, StringRef S) {
66+
return ::crc32(CRC, (const Bytef *)S.data(), S.size());
67+
}
68+
#endif

llvm/unittests/Support/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ add_llvm_unittest(SupportTests
1818
CommandLineTest.cpp
1919
CompressionTest.cpp
2020
ConvertUTFTest.cpp
21+
CRCTest.cpp
2122
DataExtractorTest.cpp
2223
DebugTest.cpp
2324
DebugCounterTest.cpp

llvm/unittests/Support/CRCTest.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===- llvm/unittest/Support/CRCTest.cpp - CRC tests ----------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file implements unit tests for CRC calculation functions.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "llvm/Support/CRC.h"
14+
#include "gtest/gtest.h"
15+
16+
using namespace llvm;
17+
18+
namespace {
19+
20+
TEST(CRCTest, CRC32) {
21+
EXPECT_EQ(0x414FA339U,
22+
llvm::crc32(
23+
0, StringRef("The quick brown fox jumps over the lazy dog")));
24+
// CRC-32/ISO-HDLC test vector
25+
// http://reveng.sourceforge.net/crc-catalogue/17plus.htm#crc.cat.crc-32c
26+
EXPECT_EQ(0xCBF43926U, llvm::crc32(0, StringRef("123456789")));
27+
}
28+
29+
} // end anonymous namespace

0 commit comments

Comments
 (0)