From 18873b22be08dbd91e910c1cb53b5d9aa5eb38cf Mon Sep 17 00:00:00 2001 From: Eugene Leviant Date: Mon, 8 Apr 2019 12:31:12 +0000 Subject: [PATCH] Attempt to recommit r357901 llvm-svn: 357905 --- llvm/include/llvm/Support/CRC.h | 25 ++++++++ llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 3 +- llvm/lib/Support/CMakeLists.txt | 1 + llvm/lib/Support/CRC.cpp | 68 ++++++++++++++++++++++ llvm/unittests/Support/CMakeLists.txt | 1 + llvm/unittests/Support/CRCTest.cpp | 29 +++++++++ 6 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 llvm/include/llvm/Support/CRC.h create mode 100644 llvm/lib/Support/CRC.cpp create mode 100644 llvm/unittests/Support/CRCTest.cpp diff --git a/llvm/include/llvm/Support/CRC.h b/llvm/include/llvm/Support/CRC.h new file mode 100644 index 000000000000..6ea8e3edcea4 --- /dev/null +++ b/llvm/include/llvm/Support/CRC.h @@ -0,0 +1,25 @@ +//===-- llvm/Support/CRC.h - Cyclic Redundancy Check-------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains basic functions for calculating Cyclic Redundancy Check +// or CRC. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_CRC_H +#define LLVM_SUPPORT_CRC_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { +/// zlib independent CRC32 calculation. +uint32_t crc32(uint32_t CRC, StringRef S); +} // end namespace llvm + +#endif diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 43c65c43c748..52192287b719 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -23,6 +23,7 @@ #include "llvm/Object/COFF.h" #include "llvm/Object/MachO.h" #include "llvm/Object/MachOUniversal.h" +#include "llvm/Support/CRC.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compression.h" #include "llvm/Support/DataExtractor.h" @@ -163,7 +164,7 @@ bool checkFileCRC(StringRef Path, uint32_t CRCHash) { MemoryBuffer::getFileOrSTDIN(Path); if (!MB) return false; - return !zlib::isAvailable() || CRCHash == zlib::crc32(MB.get()->getBuffer()); + return CRCHash == crc32(0, MB.get()->getBuffer()); } bool findDebugBinary(const std::string &OrigPath, diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt index c5846ad6c811..7dfa97c53568 100644 --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -76,6 +76,7 @@ add_llvm_library(LLVMSupport CodeGenCoverage.cpp CommandLine.cpp Compression.cpp + CRC.cpp ConvertUTF.cpp ConvertUTFWrapper.cpp CrashRecoveryContext.cpp diff --git a/llvm/lib/Support/CRC.cpp b/llvm/lib/Support/CRC.cpp new file mode 100644 index 000000000000..fd98f3a24003 --- /dev/null +++ b/llvm/lib/Support/CRC.cpp @@ -0,0 +1,68 @@ +//===--- CRC.cpp - Cyclic Redundancy Check implementation -----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements llvm::crc32 function. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/CRC.h" +#include "llvm/Config/config.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Threading.h" +#include + +using namespace llvm; + +#if LLVM_ENABLE_ZLIB == 0 || !HAVE_ZLIB_H +using CRC32Table = std::array; + +static void initCRC32Table(CRC32Table *Tbl) { + auto Shuffle = [](uint32_t V) { + return (V & 1) ? (V >> 1) ^ 0xEDB88320U : V >> 1; + }; + + for (size_t I = 0; I < Tbl->size(); ++I) { + uint32_t V = Shuffle(I); + V = Shuffle(V); + V = Shuffle(V); + V = Shuffle(V); + V = Shuffle(V); + V = Shuffle(V); + V = Shuffle(V); + (*Tbl)[I] = Shuffle(V); + } +} + +uint32_t llvm::crc32(uint32_t CRC, StringRef S) { + static llvm::once_flag InitFlag; + static CRC32Table Tbl; + llvm::call_once(InitFlag, initCRC32Table, &Tbl); + + const uint8_t *P = reinterpret_cast(S.data()); + size_t Len = S.size(); + CRC ^= 0xFFFFFFFFU; + for (; Len >= 8; Len -= 8) { + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + } + while (Len--) + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + return CRC ^ 0xFFFFFFFFU; +} +#else +#include +uint32_t llvm::crc32(uint32_t CRC, StringRef S) { + return ::crc32(CRC, (const Bytef *)S.data(), S.size()); +} +#endif diff --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt index 40bf93940024..12c983df50cc 100644 --- a/llvm/unittests/Support/CMakeLists.txt +++ b/llvm/unittests/Support/CMakeLists.txt @@ -18,6 +18,7 @@ add_llvm_unittest(SupportTests CommandLineTest.cpp CompressionTest.cpp ConvertUTFTest.cpp + CRCTest.cpp DataExtractorTest.cpp DebugTest.cpp DebugCounterTest.cpp diff --git a/llvm/unittests/Support/CRCTest.cpp b/llvm/unittests/Support/CRCTest.cpp new file mode 100644 index 000000000000..71afb0a4789f --- /dev/null +++ b/llvm/unittests/Support/CRCTest.cpp @@ -0,0 +1,29 @@ +//===- llvm/unittest/Support/CRCTest.cpp - CRC tests ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements unit tests for CRC calculation functions. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/CRC.h" +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +TEST(CRCTest, CRC32) { + EXPECT_EQ(0x414FA339U, + llvm::crc32( + 0, StringRef("The quick brown fox jumps over the lazy dog"))); + // CRC-32/ISO-HDLC test vector + // http://reveng.sourceforge.net/crc-catalogue/17plus.htm#crc.cat.crc-32c + EXPECT_EQ(0xCBF43926U, llvm::crc32(0, StringRef("123456789"))); +} + +} // end anonymous namespace