summaryrefslogtreecommitdiffstats
path: root/contrib/libs/libfuzzer12
diff options
context:
space:
mode:
authorthegeorg <[email protected]>2022-11-07 19:34:08 +0300
committerthegeorg <[email protected]>2022-11-07 19:34:08 +0300
commit50f76e264c70a223a34b24aa59e97bff97128f4c (patch)
treee604247a10f09df6158c172577b9bfa431f1e1b5 /contrib/libs/libfuzzer12
parent278a58c5af63dbd7f7a6d8b8d92dc246651242da (diff)
Switch fuzz tests to contrib/libs/libfuzzer
Diffstat (limited to 'contrib/libs/libfuzzer12')
-rw-r--r--contrib/libs/libfuzzer12/CODE_OWNERS.TXT53
-rw-r--r--contrib/libs/libfuzzer12/CREDITS.TXT36
-rw-r--r--contrib/libs/libfuzzer12/FuzzerBuiltins.h35
-rw-r--r--contrib/libs/libfuzzer12/FuzzerBuiltinsMsvc.h72
-rw-r--r--contrib/libs/libfuzzer12/FuzzerCommand.h178
-rw-r--r--contrib/libs/libfuzzer12/FuzzerCorpus.h581
-rw-r--r--contrib/libs/libfuzzer12/FuzzerCrossOver.cpp51
-rw-r--r--contrib/libs/libfuzzer12/FuzzerDataFlowTrace.cpp286
-rw-r--r--contrib/libs/libfuzzer12/FuzzerDataFlowTrace.h135
-rw-r--r--contrib/libs/libfuzzer12/FuzzerDefs.h77
-rw-r--r--contrib/libs/libfuzzer12/FuzzerDictionary.h118
-rw-r--r--contrib/libs/libfuzzer12/FuzzerDriver.cpp933
-rw-r--r--contrib/libs/libfuzzer12/FuzzerExtFunctions.def51
-rw-r--r--contrib/libs/libfuzzer12/FuzzerExtFunctions.h34
-rw-r--r--contrib/libs/libfuzzer12/FuzzerExtFunctionsDlsym.cpp51
-rw-r--r--contrib/libs/libfuzzer12/FuzzerExtFunctionsWeak.cpp54
-rw-r--r--contrib/libs/libfuzzer12/FuzzerExtFunctionsWindows.cpp82
-rw-r--r--contrib/libs/libfuzzer12/FuzzerExtraCounters.cpp42
-rw-r--r--contrib/libs/libfuzzer12/FuzzerFlags.def205
-rw-r--r--contrib/libs/libfuzzer12/FuzzerFork.cpp413
-rw-r--r--contrib/libs/libfuzzer12/FuzzerFork.h24
-rw-r--r--contrib/libs/libfuzzer12/FuzzerIO.cpp204
-rw-r--r--contrib/libs/libfuzzer12/FuzzerIO.h112
-rw-r--r--contrib/libs/libfuzzer12/FuzzerIOPosix.cpp180
-rw-r--r--contrib/libs/libfuzzer12/FuzzerIOWindows.cpp425
-rw-r--r--contrib/libs/libfuzzer12/FuzzerInterface.h80
-rw-r--r--contrib/libs/libfuzzer12/FuzzerInternal.h174
-rw-r--r--contrib/libs/libfuzzer12/FuzzerLoop.cpp921
-rw-r--r--contrib/libs/libfuzzer12/FuzzerMain.cpp21
-rw-r--r--contrib/libs/libfuzzer12/FuzzerMerge.cpp402
-rw-r--r--contrib/libs/libfuzzer12/FuzzerMerge.h87
-rw-r--r--contrib/libs/libfuzzer12/FuzzerMutate.cpp578
-rw-r--r--contrib/libs/libfuzzer12/FuzzerMutate.h156
-rw-r--r--contrib/libs/libfuzzer12/FuzzerOptions.h93
-rw-r--r--contrib/libs/libfuzzer12/FuzzerPlatform.h147
-rw-r--r--contrib/libs/libfuzzer12/FuzzerRandom.h38
-rw-r--r--contrib/libs/libfuzzer12/FuzzerSHA1.cpp223
-rw-r--r--contrib/libs/libfuzzer12/FuzzerSHA1.h32
-rw-r--r--contrib/libs/libfuzzer12/FuzzerTracePC.cpp673
-rw-r--r--contrib/libs/libfuzzer12/FuzzerTracePC.h291
-rw-r--r--contrib/libs/libfuzzer12/FuzzerUtil.cpp236
-rw-r--r--contrib/libs/libfuzzer12/FuzzerUtil.h117
-rw-r--r--contrib/libs/libfuzzer12/FuzzerUtilDarwin.cpp170
-rw-r--r--contrib/libs/libfuzzer12/FuzzerUtilLinux.cpp41
-rw-r--r--contrib/libs/libfuzzer12/FuzzerUtilPosix.cpp185
-rw-r--r--contrib/libs/libfuzzer12/FuzzerUtilWindows.cpp229
-rw-r--r--contrib/libs/libfuzzer12/FuzzerValueBitMap.h73
-rw-r--r--contrib/libs/libfuzzer12/LICENSE.TXT311
-rw-r--r--contrib/libs/libfuzzer12/README.txt1
49 files changed, 0 insertions, 9711 deletions
diff --git a/contrib/libs/libfuzzer12/CODE_OWNERS.TXT b/contrib/libs/libfuzzer12/CODE_OWNERS.TXT
deleted file mode 100644
index 125487816bc..00000000000
--- a/contrib/libs/libfuzzer12/CODE_OWNERS.TXT
+++ /dev/null
@@ -1,53 +0,0 @@
-This file is a list of the people responsible for ensuring that patches for a
-particular part of compiler-rt are reviewed, either by themself or by
-someone else. They are also the gatekeepers for their part of compiler-rt, with
-the final word on what goes in or not.
-
-The list is sorted by surname and formatted to allow easy grepping and
-beautification by scripts. The fields are: name (N), email (E), web-address
-(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
-(S).
-
-N: Peter Collingbourne
-D: DataFlowSanitizer
-
-N: Daniel Dunbar
-D: Makefile build
-
-N: Timur Iskhodzhanov
-D: AddressSanitizer for Windows
-
-N: Howard Hinnant
-D: builtins library
-
-N: Alexander Potapenko
-D: MacOS/iOS port of sanitizers
-
-N: Alexey Samsonov
-D: CMake build, test suite
-
-N: Kostya Serebryany
-D: AddressSanitizer, sanitizer_common, porting sanitizers to another platforms, LeakSanitizer
-
-N: Richard Smith
-D: UndefinedBehaviorSanitizer
-
-N: Evgeniy Stepanov
-D: MemorySanitizer, Android port of sanitizers
-
-N: Dmitry Vyukov
-D: ThreadSanitizer
-
-N: Bill Wendling
-D: Profile runtime library
diff --git a/contrib/libs/libfuzzer12/CREDITS.TXT b/contrib/libs/libfuzzer12/CREDITS.TXT
deleted file mode 100644
index 6964eba020b..00000000000
--- a/contrib/libs/libfuzzer12/CREDITS.TXT
+++ /dev/null
@@ -1,36 +0,0 @@
-This file is a partial list of people who have contributed to the LLVM/CompilerRT
-project. If you have contributed a patch or made some other contribution to
-LLVM/CompilerRT, please submit a patch to this file to add yourself, and it will be
-done!
-
-The list is sorted by surname and formatted to allow easy grepping and
-beautification by scripts. The fields are: name (N), email (E), web-address
-(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
-(S).
-
-N: Craig van Vliet
-W: http://www.auroraux.org
-D: Code style and Readability fixes.
-
-N: Edward O'Callaghan
-W: http://www.auroraux.org
-D: CMake'ify Compiler-RT build system
-D: Maintain Solaris & AuroraUX ports of Compiler-RT
-
-N: Howard Hinnant
-D: Architect and primary author of compiler-rt
-
-N: Guan-Hong Liu
-D: IEEE Quad-precision functions
-
-N: Joerg Sonnenberger
-D: Maintains NetBSD port.
-
-N: Matt Thomas
-D: ARM improvements.
diff --git a/contrib/libs/libfuzzer12/FuzzerBuiltins.h b/contrib/libs/libfuzzer12/FuzzerBuiltins.h
deleted file mode 100644
index 4c0ada82662..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerBuiltins.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===- FuzzerBuiltins.h - Internal header for builtins ----------*- 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
-//
-//===----------------------------------------------------------------------===//
-// Wrapper functions and marcos around builtin functions.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_BUILTINS_H
-#define LLVM_FUZZER_BUILTINS_H
-
-#include "FuzzerPlatform.h"
-
-#if !LIBFUZZER_MSVC
-#include <cstdint>
-
-#define GET_CALLER_PC() __builtin_return_address(0)
-
-namespace fuzzer {
-
-inline uint8_t Bswap(uint8_t x) { return x; }
-inline uint16_t Bswap(uint16_t x) { return __builtin_bswap16(x); }
-inline uint32_t Bswap(uint32_t x) { return __builtin_bswap32(x); }
-inline uint64_t Bswap(uint64_t x) { return __builtin_bswap64(x); }
-
-inline uint32_t Clzll(unsigned long long X) { return __builtin_clzll(X); }
-inline uint32_t Clz(unsigned long long X) { return __builtin_clz(X); }
-inline int Popcountll(unsigned long long X) { return __builtin_popcountll(X); }
-
-} // namespace fuzzer
-
-#endif // !LIBFUZZER_MSVC
-#endif // LLVM_FUZZER_BUILTINS_H
diff --git a/contrib/libs/libfuzzer12/FuzzerBuiltinsMsvc.h b/contrib/libs/libfuzzer12/FuzzerBuiltinsMsvc.h
deleted file mode 100644
index c5bec9787d8..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerBuiltinsMsvc.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//===- FuzzerBuiltinsMSVC.h - Internal header for builtins ------*- 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
-//
-//===----------------------------------------------------------------------===//
-// Wrapper functions and marcos that use intrinsics instead of builtin functions
-// which cannot be compiled by MSVC.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_BUILTINS_MSVC_H
-#define LLVM_FUZZER_BUILTINS_MSVC_H
-
-#include "FuzzerPlatform.h"
-
-#if LIBFUZZER_MSVC
-#include <intrin.h>
-#include <cstdint>
-#include <cstdlib>
-
-// __builtin_return_address() cannot be compiled with MSVC. Use the equivalent
-// from <intrin.h>
-#define GET_CALLER_PC() _ReturnAddress()
-
-namespace fuzzer {
-
-inline uint8_t Bswap(uint8_t x) { return x; }
-// Use alternatives to __builtin functions from <stdlib.h> and <intrin.h> on
-// Windows since the builtins are not supported by MSVC.
-inline uint16_t Bswap(uint16_t x) { return _byteswap_ushort(x); }
-inline uint32_t Bswap(uint32_t x) { return _byteswap_ulong(x); }
-inline uint64_t Bswap(uint64_t x) { return _byteswap_uint64(x); }
-
-// The functions below were mostly copied from
-// compiler-rt/lib/builtins/int_lib.h which defines the __builtin functions used
-// outside of Windows.
-inline uint32_t Clzll(uint64_t X) {
- unsigned long LeadZeroIdx = 0;
-
-#if !defined(_M_ARM) && !defined(_M_X64)
- // Scan the high 32 bits.
- if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X >> 32)))
- return static_cast<int>(63 - (LeadZeroIdx + 32)); // Create a bit offset from the MSB.
- // Scan the low 32 bits.
- if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X)))
- return static_cast<int>(63 - LeadZeroIdx);
-
-#else
- if (_BitScanReverse64(&LeadZeroIdx, X)) return 63 - LeadZeroIdx;
-#endif
- return 64;
-}
-
-inline uint32_t Clz(uint32_t X) {
- unsigned long LeadZeroIdx = 0;
- if (_BitScanReverse(&LeadZeroIdx, X)) return 31 - LeadZeroIdx;
- return 32;
-}
-
-inline int Popcountll(unsigned long long X) {
-#if !defined(_M_ARM) && !defined(_M_X64)
- return __popcnt(X) + __popcnt(X >> 32);
-#else
- return __popcnt64(X);
-#endif
-}
-
-} // namespace fuzzer
-
-#endif // LIBFUZER_MSVC
-#endif // LLVM_FUZZER_BUILTINS_MSVC_H
diff --git a/contrib/libs/libfuzzer12/FuzzerCommand.h b/contrib/libs/libfuzzer12/FuzzerCommand.h
deleted file mode 100644
index 87308864af5..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerCommand.h
+++ /dev/null
@@ -1,178 +0,0 @@
-//===- FuzzerCommand.h - Interface representing a process -------*- 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
-//
-//===----------------------------------------------------------------------===//
-// FuzzerCommand represents a command to run in a subprocess. It allows callers
-// to manage command line arguments and output and error streams.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_COMMAND_H
-#define LLVM_FUZZER_COMMAND_H
-
-#include "FuzzerDefs.h"
-#include "FuzzerIO.h"
-
-#include <algorithm>
-#include <sstream>
-#include <string>
-#include <vector>
-
-namespace fuzzer {
-
-class Command final {
-public:
- // This command line flag is used to indicate that the remaining command line
- // is immutable, meaning this flag effectively marks the end of the mutable
- // argument list.
- static inline const char *ignoreRemainingArgs() {
- return "-ignore_remaining_args=1";
- }
-
- Command() : CombinedOutAndErr(false) {}
-
- explicit Command(const Vector<std::string> &ArgsToAdd)
- : Args(ArgsToAdd), CombinedOutAndErr(false) {}
-
- explicit Command(const Command &Other)
- : Args(Other.Args), CombinedOutAndErr(Other.CombinedOutAndErr),
- OutputFile(Other.OutputFile) {}
-
- Command &operator=(const Command &Other) {
- Args = Other.Args;
- CombinedOutAndErr = Other.CombinedOutAndErr;
- OutputFile = Other.OutputFile;
- return *this;
- }
-
- ~Command() {}
-
- // Returns true if the given Arg is present in Args. Only checks up to
- // "-ignore_remaining_args=1".
- bool hasArgument(const std::string &Arg) const {
- auto i = endMutableArgs();
- return std::find(Args.begin(), i, Arg) != i;
- }
-
- // Gets all of the current command line arguments, **including** those after
- // "-ignore-remaining-args=1".
- const Vector<std::string> &getArguments() const { return Args; }
-
- // Adds the given argument before "-ignore_remaining_args=1", or at the end
- // if that flag isn't present.
- void addArgument(const std::string &Arg) {
- Args.insert(endMutableArgs(), Arg);
- }
-
- // Adds all given arguments before "-ignore_remaining_args=1", or at the end
- // if that flag isn't present.
- void addArguments(const Vector<std::string> &ArgsToAdd) {
- Args.insert(endMutableArgs(), ArgsToAdd.begin(), ArgsToAdd.end());
- }
-
- // Removes the given argument from the command argument list. Ignores any
- // occurrences after "-ignore_remaining_args=1", if present.
- void removeArgument(const std::string &Arg) {
- auto i = endMutableArgs();
- Args.erase(std::remove(Args.begin(), i, Arg), i);
- }
-
- // Like hasArgument, but checks for "-[Flag]=...".
- bool hasFlag(const std::string &Flag) const {
- std::string Arg("-" + Flag + "=");
- auto IsMatch = [&](const std::string &Other) {
- return Arg.compare(0, std::string::npos, Other, 0, Arg.length()) == 0;
- };
- return std::any_of(Args.begin(), endMutableArgs(), IsMatch);
- }
-
- // Returns the value of the first instance of a given flag, or an empty string
- // if the flag isn't present. Ignores any occurrences after
- // "-ignore_remaining_args=1", if present.
- std::string getFlagValue(const std::string &Flag) const {
- std::string Arg("-" + Flag + "=");
- auto IsMatch = [&](const std::string &Other) {
- return Arg.compare(0, std::string::npos, Other, 0, Arg.length()) == 0;
- };
- auto i = endMutableArgs();
- auto j = std::find_if(Args.begin(), i, IsMatch);
- std::string result;
- if (j != i) {
- result = j->substr(Arg.length());
- }
- return result;
- }
-
- // Like AddArgument, but adds "-[Flag]=[Value]".
- void addFlag(const std::string &Flag, const std::string &Value) {
- addArgument("-" + Flag + "=" + Value);
- }
-
- // Like RemoveArgument, but removes "-[Flag]=...".
- void removeFlag(const std::string &Flag) {
- std::string Arg("-" + Flag + "=");
- auto IsMatch = [&](const std::string &Other) {
- return Arg.compare(0, std::string::npos, Other, 0, Arg.length()) == 0;
- };
- auto i = endMutableArgs();
- Args.erase(std::remove_if(Args.begin(), i, IsMatch), i);
- }
-
- // Returns whether the command's stdout is being written to an output file.
- bool hasOutputFile() const { return !OutputFile.empty(); }
-
- // Returns the currently set output file.
- const std::string &getOutputFile() const { return OutputFile; }
-
- // Configures the command to redirect its output to the name file.
- void setOutputFile(const std::string &FileName) { OutputFile = FileName; }
-
- // Returns whether the command's stderr is redirected to stdout.
- bool isOutAndErrCombined() const { return CombinedOutAndErr; }
-
- // Sets whether to redirect the command's stderr to its stdout.
- void combineOutAndErr(bool combine = true) { CombinedOutAndErr = combine; }
-
- // Returns a string representation of the command. On many systems this will
- // be the equivalent command line.
- std::string toString() const {
- std::stringstream SS;
- for (auto arg : getArguments())
- SS << arg << " ";
- if (hasOutputFile())
- SS << ">" << getOutputFile() << " ";
- if (isOutAndErrCombined())
- SS << "2>&1 ";
- std::string result = SS.str();
- if (!result.empty())
- result = result.substr(0, result.length() - 1);
- return result;
- }
-
-private:
- Command(Command &&Other) = delete;
- Command &operator=(Command &&Other) = delete;
-
- Vector<std::string>::iterator endMutableArgs() {
- return std::find(Args.begin(), Args.end(), ignoreRemainingArgs());
- }
-
- Vector<std::string>::const_iterator endMutableArgs() const {
- return std::find(Args.begin(), Args.end(), ignoreRemainingArgs());
- }
-
- // The command arguments. Args[0] is the command name.
- Vector<std::string> Args;
-
- // True indicates stderr is redirected to stdout.
- bool CombinedOutAndErr;
-
- // If not empty, stdout is redirected to the named file.
- std::string OutputFile;
-};
-
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_COMMAND_H
diff --git a/contrib/libs/libfuzzer12/FuzzerCorpus.h b/contrib/libs/libfuzzer12/FuzzerCorpus.h
deleted file mode 100644
index daea4f5213b..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerCorpus.h
+++ /dev/null
@@ -1,581 +0,0 @@
-//===- FuzzerCorpus.h - Internal header for the Fuzzer ----------*- 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
-//
-//===----------------------------------------------------------------------===//
-// fuzzer::InputCorpus
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_CORPUS
-#define LLVM_FUZZER_CORPUS
-
-#include "FuzzerDataFlowTrace.h"
-#include "FuzzerDefs.h"
-#include "FuzzerIO.h"
-#include "FuzzerRandom.h"
-#include "FuzzerSHA1.h"
-#include "FuzzerTracePC.h"
-#include <algorithm>
-#include <chrono>
-#include <numeric>
-#include <random>
-#include <unordered_set>
-
-namespace fuzzer {
-
-struct InputInfo {
- Unit U; // The actual input data.
- std::chrono::microseconds TimeOfUnit;
- uint8_t Sha1[kSHA1NumBytes]; // Checksum.
- // Number of features that this input has and no smaller input has.
- size_t NumFeatures = 0;
- size_t Tmp = 0; // Used by ValidateFeatureSet.
- // Stats.
- size_t NumExecutedMutations = 0;
- size_t NumSuccessfullMutations = 0;
- bool NeverReduce = false;
- bool MayDeleteFile = false;
- bool Reduced = false;
- bool HasFocusFunction = false;
- Vector<uint32_t> UniqFeatureSet;
- Vector<uint8_t> DataFlowTraceForFocusFunction;
- // Power schedule.
- bool NeedsEnergyUpdate = false;
- double Energy = 0.0;
- size_t SumIncidence = 0;
- Vector<std::pair<uint32_t, uint16_t>> FeatureFreqs;
-
- // Delete feature Idx and its frequency from FeatureFreqs.
- bool DeleteFeatureFreq(uint32_t Idx) {
- if (FeatureFreqs.empty())
- return false;
-
- // Binary search over local feature frequencies sorted by index.
- auto Lower = std::lower_bound(FeatureFreqs.begin(), FeatureFreqs.end(),
- std::pair<uint32_t, uint16_t>(Idx, 0));
-
- if (Lower != FeatureFreqs.end() && Lower->first == Idx) {
- FeatureFreqs.erase(Lower);
- return true;
- }
- return false;
- }
-
- // Assign more energy to a high-entropy seed, i.e., that reveals more
- // information about the globally rare features in the neighborhood of the
- // seed. Since we do not know the entropy of a seed that has never been
- // executed we assign fresh seeds maximum entropy and let II->Energy approach
- // the true entropy from above. If ScalePerExecTime is true, the computed
- // entropy is scaled based on how fast this input executes compared to the
- // average execution time of inputs. The faster an input executes, the more
- // energy gets assigned to the input.
- void UpdateEnergy(size_t GlobalNumberOfFeatures, bool ScalePerExecTime,
- std::chrono::microseconds AverageUnitExecutionTime) {
- Energy = 0.0;
- SumIncidence = 0;
-
- // Apply add-one smoothing to locally discovered features.
- for (auto F : FeatureFreqs) {
- size_t LocalIncidence = F.second + 1;
- Energy -= LocalIncidence * logl(LocalIncidence);
- SumIncidence += LocalIncidence;
- }
-
- // Apply add-one smoothing to locally undiscovered features.
- // PreciseEnergy -= 0; // since logl(1.0) == 0)
- SumIncidence += (GlobalNumberOfFeatures - FeatureFreqs.size());
-
- // Add a single locally abundant feature apply add-one smoothing.
- size_t AbdIncidence = NumExecutedMutations + 1;
- Energy -= AbdIncidence * logl(AbdIncidence);
- SumIncidence += AbdIncidence;
-
- // Normalize.
- if (SumIncidence != 0)
- Energy = (Energy / SumIncidence) + logl(SumIncidence);
-
- if (ScalePerExecTime) {
- // Scaling to favor inputs with lower execution time.
- uint32_t PerfScore = 100;
- if (TimeOfUnit.count() > AverageUnitExecutionTime.count() * 10)
- PerfScore = 10;
- else if (TimeOfUnit.count() > AverageUnitExecutionTime.count() * 4)
- PerfScore = 25;
- else if (TimeOfUnit.count() > AverageUnitExecutionTime.count() * 2)
- PerfScore = 50;
- else if (TimeOfUnit.count() * 3 > AverageUnitExecutionTime.count() * 4)
- PerfScore = 75;
- else if (TimeOfUnit.count() * 4 < AverageUnitExecutionTime.count())
- PerfScore = 300;
- else if (TimeOfUnit.count() * 3 < AverageUnitExecutionTime.count())
- PerfScore = 200;
- else if (TimeOfUnit.count() * 2 < AverageUnitExecutionTime.count())
- PerfScore = 150;
-
- Energy *= PerfScore;
- }
- }
-
- // Increment the frequency of the feature Idx.
- void UpdateFeatureFrequency(uint32_t Idx) {
- NeedsEnergyUpdate = true;
-
- // The local feature frequencies is an ordered vector of pairs.
- // If there are no local feature frequencies, push_back preserves order.
- // Set the feature frequency for feature Idx32 to 1.
- if (FeatureFreqs.empty()) {
- FeatureFreqs.push_back(std::pair<uint32_t, uint16_t>(Idx, 1));
- return;
- }
-
- // Binary search over local feature frequencies sorted by index.
- auto Lower = std::lower_bound(FeatureFreqs.begin(), FeatureFreqs.end(),
- std::pair<uint32_t, uint16_t>(Idx, 0));
-
- // If feature Idx32 already exists, increment its frequency.
- // Otherwise, insert a new pair right after the next lower index.
- if (Lower != FeatureFreqs.end() && Lower->first == Idx) {
- Lower->second++;
- } else {
- FeatureFreqs.insert(Lower, std::pair<uint32_t, uint16_t>(Idx, 1));
- }
- }
-};
-
-struct EntropicOptions {
- bool Enabled;
- size_t NumberOfRarestFeatures;
- size_t FeatureFrequencyThreshold;
- bool ScalePerExecTime;
-};
-
-class InputCorpus {
- static const uint32_t kFeatureSetSize = 1 << 21;
- static const uint8_t kMaxMutationFactor = 20;
- static const size_t kSparseEnergyUpdates = 100;
-
- size_t NumExecutedMutations = 0;
-
- EntropicOptions Entropic;
-
-public:
- InputCorpus(const std::string &OutputCorpus, EntropicOptions Entropic)
- : Entropic(Entropic), OutputCorpus(OutputCorpus) {
- memset(InputSizesPerFeature, 0, sizeof(InputSizesPerFeature));
- memset(SmallestElementPerFeature, 0, sizeof(SmallestElementPerFeature));
- }
- ~InputCorpus() {
- for (auto II : Inputs)
- delete II;
- }
- size_t size() const { return Inputs.size(); }
- size_t SizeInBytes() const {
- size_t Res = 0;
- for (auto II : Inputs)
- Res += II->U.size();
- return Res;
- }
- size_t NumActiveUnits() const {
- size_t Res = 0;
- for (auto II : Inputs)
- Res += !II->U.empty();
- return Res;
- }
- size_t MaxInputSize() const {
- size_t Res = 0;
- for (auto II : Inputs)
- Res = std::max(Res, II->U.size());
- return Res;
- }
- void IncrementNumExecutedMutations() { NumExecutedMutations++; }
-
- size_t NumInputsThatTouchFocusFunction() {
- return std::count_if(Inputs.begin(), Inputs.end(), [](const InputInfo *II) {
- return II->HasFocusFunction;
- });
- }
-
- size_t NumInputsWithDataFlowTrace() {
- return std::count_if(Inputs.begin(), Inputs.end(), [](const InputInfo *II) {
- return !II->DataFlowTraceForFocusFunction.empty();
- });
- }
-
- bool empty() const { return Inputs.empty(); }
- const Unit &operator[] (size_t Idx) const { return Inputs[Idx]->U; }
- InputInfo *AddToCorpus(const Unit &U, size_t NumFeatures, bool MayDeleteFile,
- bool HasFocusFunction, bool NeverReduce,
- std::chrono::microseconds TimeOfUnit,
- const Vector<uint32_t> &FeatureSet,
- const DataFlowTrace &DFT, const InputInfo *BaseII) {
- assert(!U.empty());
- if (FeatureDebug)
- Printf("ADD_TO_CORPUS %zd NF %zd\n", Inputs.size(), NumFeatures);
- Inputs.push_back(new InputInfo());
- InputInfo &II = *Inputs.back();
- II.U = U;
- II.NumFeatures = NumFeatures;
- II.NeverReduce = NeverReduce;
- II.TimeOfUnit = TimeOfUnit;
- II.MayDeleteFile = MayDeleteFile;
- II.UniqFeatureSet = FeatureSet;
- II.HasFocusFunction = HasFocusFunction;
- // Assign maximal energy to the new seed.
- II.Energy = RareFeatures.empty() ? 1.0 : log(RareFeatures.size());
- II.SumIncidence = RareFeatures.size();
- II.NeedsEnergyUpdate = false;
- std::sort(II.UniqFeatureSet.begin(), II.UniqFeatureSet.end());
- ComputeSHA1(U.data(), U.size(), II.Sha1);
- auto Sha1Str = Sha1ToString(II.Sha1);
- Hashes.insert(Sha1Str);
- if (HasFocusFunction)
- if (auto V = DFT.Get(Sha1Str))
- II.DataFlowTraceForFocusFunction = *V;
- // This is a gross heuristic.
- // Ideally, when we add an element to a corpus we need to know its DFT.
- // But if we don't, we'll use the DFT of its base input.
- if (II.DataFlowTraceForFocusFunction.empty() && BaseII)
- II.DataFlowTraceForFocusFunction = BaseII->DataFlowTraceForFocusFunction;
- DistributionNeedsUpdate = true;
- PrintCorpus();
- // ValidateFeatureSet();
- return &II;
- }
-
- // Debug-only
- void PrintUnit(const Unit &U) {
- if (!FeatureDebug) return;
- for (uint8_t C : U) {
- if (C != 'F' && C != 'U' && C != 'Z')
- C = '.';
- Printf("%c", C);
- }
- }
-
- // Debug-only
- void PrintFeatureSet(const Vector<uint32_t> &FeatureSet) {
- if (!FeatureDebug) return;
- Printf("{");
- for (uint32_t Feature: FeatureSet)
- Printf("%u,", Feature);
- Printf("}");
- }
-
- // Debug-only
- void PrintCorpus() {
- if (!FeatureDebug) return;
- Printf("======= CORPUS:\n");
- int i = 0;
- for (auto II : Inputs) {
- if (std::find(II->U.begin(), II->U.end(), 'F') != II->U.end()) {
- Printf("[%2d] ", i);
- Printf("%s sz=%zd ", Sha1ToString(II->Sha1).c_str(), II->U.size());
- PrintUnit(II->U);
- Printf(" ");
- PrintFeatureSet(II->UniqFeatureSet);
- Printf("\n");
- }
- i++;
- }
- }
-
- void Replace(InputInfo *II, const Unit &U) {
- assert(II->U.size() > U.size());
- Hashes.erase(Sha1ToString(II->Sha1));
- DeleteFile(*II);
- ComputeSHA1(U.data(), U.size(), II->Sha1);
- Hashes.insert(Sha1ToString(II->Sha1));
- II->U = U;
- II->Reduced = true;
- DistributionNeedsUpdate = true;
- }
-
- bool HasUnit(const Unit &U) { return Hashes.count(Hash(U)); }
- bool HasUnit(const std::string &H) { return Hashes.count(H); }
- InputInfo &ChooseUnitToMutate(Random &Rand) {
- InputInfo &II = *Inputs[ChooseUnitIdxToMutate(Rand)];
- assert(!II.U.empty());
- return II;
- }
-
- InputInfo &ChooseUnitToCrossOverWith(Random &Rand, bool UniformDist) {
- if (!UniformDist) {
- return ChooseUnitToMutate(Rand);
- }
- InputInfo &II = *Inputs[Rand(Inputs.size())];
- assert(!II.U.empty());
- return II;
- }
-
- // Returns an index of random unit from the corpus to mutate.
- size_t ChooseUnitIdxToMutate(Random &Rand) {
- UpdateCorpusDistribution(Rand);
- size_t Idx = static_cast<size_t>(CorpusDistribution(Rand));
- assert(Idx < Inputs.size());
- return Idx;
- }
-
- void PrintStats() {
- for (size_t i = 0; i < Inputs.size(); i++) {
- const auto &II = *Inputs[i];
- Printf(" [% 3zd %s] sz: % 5zd runs: % 5zd succ: % 5zd focus: %d\n", i,
- Sha1ToString(II.Sha1).c_str(), II.U.size(),
- II.NumExecutedMutations, II.NumSuccessfullMutations, II.HasFocusFunction);
- }
- }
-
- void PrintFeatureSet() {
- for (size_t i = 0; i < kFeatureSetSize; i++) {
- if(size_t Sz = GetFeature(i))
- Printf("[%zd: id %zd sz%zd] ", i, SmallestElementPerFeature[i], Sz);
- }
- Printf("\n\t");
- for (size_t i = 0; i < Inputs.size(); i++)
- if (size_t N = Inputs[i]->NumFeatures)
- Printf(" %zd=>%zd ", i, N);
- Printf("\n");
- }
-
- void DeleteFile(const InputInfo &II) {
- if (!OutputCorpus.empty() && II.MayDeleteFile)
- RemoveFile(DirPlusFile(OutputCorpus, Sha1ToString(II.Sha1)));
- }
-
- void DeleteInput(size_t Idx) {
- InputInfo &II = *Inputs[Idx];
- DeleteFile(II);
- Unit().swap(II.U);
- II.Energy = 0.0;
- II.NeedsEnergyUpdate = false;
- DistributionNeedsUpdate = true;
- if (FeatureDebug)
- Printf("EVICTED %zd\n", Idx);
- }
-
- void AddRareFeature(uint32_t Idx) {
- // Maintain *at least* TopXRarestFeatures many rare features
- // and all features with a frequency below ConsideredRare.
- // Remove all other features.
- while (RareFeatures.size() > Entropic.NumberOfRarestFeatures &&
- FreqOfMostAbundantRareFeature > Entropic.FeatureFrequencyThreshold) {
-
- // Find most and second most abbundant feature.
- uint32_t MostAbundantRareFeatureIndices[2] = {RareFeatures[0],
- RareFeatures[0]};
- size_t Delete = 0;
- for (size_t i = 0; i < RareFeatures.size(); i++) {
- uint32_t Idx2 = RareFeatures[i];
- if (GlobalFeatureFreqs[Idx2] >=
- GlobalFeatureFreqs[MostAbundantRareFeatureIndices[0]]) {
- MostAbundantRareFeatureIndices[1] = MostAbundantRareFeatureIndices[0];
- MostAbundantRareFeatureIndices[0] = Idx2;
- Delete = i;
- }
- }
-
- // Remove most abundant rare feature.
- RareFeatures[Delete] = RareFeatures.back();
- RareFeatures.pop_back();
-
- for (auto II : Inputs) {
- if (II->DeleteFeatureFreq(MostAbundantRareFeatureIndices[0]))
- II->NeedsEnergyUpdate = true;
- }
-
- // Set 2nd most abundant as the new most abundant feature count.
- FreqOfMostAbundantRareFeature =
- GlobalFeatureFreqs[MostAbundantRareFeatureIndices[1]];
- }
-
- // Add rare feature, handle collisions, and update energy.
- RareFeatures.push_back(Idx);
- GlobalFeatureFreqs[Idx] = 0;
- for (auto II : Inputs) {
- II->DeleteFeatureFreq(Idx);
-
- // Apply add-one smoothing to this locally undiscovered feature.
- // Zero energy seeds will never be fuzzed and remain zero energy.
- if (II->Energy > 0.0) {
- II->SumIncidence += 1;
- II->Energy += logl(II->SumIncidence) / II->SumIncidence;
- }
- }
-
- DistributionNeedsUpdate = true;
- }
-
- bool AddFeature(size_t Idx, uint32_t NewSize, bool Shrink) {
- assert(NewSize);
- Idx = Idx % kFeatureSetSize;
- uint32_t OldSize = GetFeature(Idx);
- if (OldSize == 0 || (Shrink && OldSize > NewSize)) {
- if (OldSize > 0) {
- size_t OldIdx = SmallestElementPerFeature[Idx];
- InputInfo &II = *Inputs[OldIdx];
- assert(II.NumFeatures > 0);
- II.NumFeatures--;
- if (II.NumFeatures == 0)
- DeleteInput(OldIdx);
- } else {
- NumAddedFeatures++;
- if (Entropic.Enabled)
- AddRareFeature((uint32_t)Idx);
- }
- NumUpdatedFeatures++;
- if (FeatureDebug)
- Printf("ADD FEATURE %zd sz %d\n", Idx, NewSize);
- SmallestElementPerFeature[Idx] = Inputs.size();
- InputSizesPerFeature[Idx] = NewSize;
- return true;
- }
- return false;
- }
-
- // Increment frequency of feature Idx globally and locally.
- void UpdateFeatureFrequency(InputInfo *II, size_t Idx) {
- uint32_t Idx32 = Idx % kFeatureSetSize;
-
- // Saturated increment.
- if (GlobalFeatureFreqs[Idx32] == 0xFFFF)
- return;
- uint16_t Freq = GlobalFeatureFreqs[Idx32]++;
-
- // Skip if abundant.
- if (Freq > FreqOfMostAbundantRareFeature ||
- std::find(RareFeatures.begin(), RareFeatures.end(), Idx32) ==
- RareFeatures.end())
- return;
-
- // Update global frequencies.
- if (Freq == FreqOfMostAbundantRareFeature)
- FreqOfMostAbundantRareFeature++;
-
- // Update local frequencies.
- if (II)
- II->UpdateFeatureFrequency(Idx32);
- }
-
- size_t NumFeatures() const { return NumAddedFeatures; }
- size_t NumFeatureUpdates() const { return NumUpdatedFeatures; }
-
-private:
-
- static const bool FeatureDebug = false;
-
- size_t GetFeature(size_t Idx) const { return InputSizesPerFeature[Idx]; }
-
- void ValidateFeatureSet() {
- if (FeatureDebug)
- PrintFeatureSet();
- for (size_t Idx = 0; Idx < kFeatureSetSize; Idx++)
- if (GetFeature(Idx))
- Inputs[SmallestElementPerFeature[Idx]]->Tmp++;
- for (auto II: Inputs) {
- if (II->Tmp != II->NumFeatures)
- Printf("ZZZ %zd %zd\n", II->Tmp, II->NumFeatures);
- assert(II->Tmp == II->NumFeatures);
- II->Tmp = 0;
- }
- }
-
- // Updates the probability distribution for the units in the corpus.
- // Must be called whenever the corpus or unit weights are changed.
- //
- // Hypothesis: inputs that maximize information about globally rare features
- // are interesting.
- void UpdateCorpusDistribution(Random &Rand) {
- // Skip update if no seeds or rare features were added/deleted.
- // Sparse updates for local change of feature frequencies,
- // i.e., randomly do not skip.
- if (!DistributionNeedsUpdate &&
- (!Entropic.Enabled || Rand(kSparseEnergyUpdates)))
- return;
-
- DistributionNeedsUpdate = false;
-
- size_t N = Inputs.size();
- assert(N);
- Intervals.resize(N + 1);
- Weights.resize(N);
- std::iota(Intervals.begin(), Intervals.end(), 0);
-
- std::chrono::microseconds AverageUnitExecutionTime(0);
- for (auto II : Inputs) {
- AverageUnitExecutionTime += II->TimeOfUnit;
- }
- AverageUnitExecutionTime /= N;
-
- bool VanillaSchedule = true;
- if (Entropic.Enabled) {
- for (auto II : Inputs) {
- if (II->NeedsEnergyUpdate && II->Energy != 0.0) {
- II->NeedsEnergyUpdate = false;
- II->UpdateEnergy(RareFeatures.size(), Entropic.ScalePerExecTime,
- AverageUnitExecutionTime);
- }
- }
-
- for (size_t i = 0; i < N; i++) {
-
- if (Inputs[i]->NumFeatures == 0) {
- // If the seed doesn't represent any features, assign zero energy.
- Weights[i] = 0.;
- } else if (Inputs[i]->NumExecutedMutations / kMaxMutationFactor >
- NumExecutedMutations / Inputs.size()) {
- // If the seed was fuzzed a lot more than average, assign zero energy.
- Weights[i] = 0.;
- } else {
- // Otherwise, simply assign the computed energy.
- Weights[i] = Inputs[i]->Energy;
- }
-
- // If energy for all seeds is zero, fall back to vanilla schedule.
- if (Weights[i] > 0.0)
- VanillaSchedule = false;
- }
- }
-
- if (VanillaSchedule) {
- for (size_t i = 0; i < N; i++)
- Weights[i] = Inputs[i]->NumFeatures
- ? (i + 1) * (Inputs[i]->HasFocusFunction ? 1000 : 1)
- : 0.;
- }
-
- if (FeatureDebug) {
- for (size_t i = 0; i < N; i++)
- Printf("%zd ", Inputs[i]->NumFeatures);
- Printf("SCORE\n");
- for (size_t i = 0; i < N; i++)
- Printf("%f ", Weights[i]);
- Printf("Weights\n");
- }
- CorpusDistribution = std::piecewise_constant_distribution<double>(
- Intervals.begin(), Intervals.end(), Weights.begin());
- }
- std::piecewise_constant_distribution<double> CorpusDistribution;
-
- Vector<double> Intervals;
- Vector<double> Weights;
-
- std::unordered_set<std::string> Hashes;
- Vector<InputInfo*> Inputs;
-
- size_t NumAddedFeatures = 0;
- size_t NumUpdatedFeatures = 0;
- uint32_t InputSizesPerFeature[kFeatureSetSize];
- uint32_t SmallestElementPerFeature[kFeatureSetSize];
-
- bool DistributionNeedsUpdate = true;
- uint16_t FreqOfMostAbundantRareFeature = 0;
- uint16_t GlobalFeatureFreqs[kFeatureSetSize] = {};
- Vector<uint32_t> RareFeatures;
-
- std::string OutputCorpus;
-};
-
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_CORPUS
diff --git a/contrib/libs/libfuzzer12/FuzzerCrossOver.cpp b/contrib/libs/libfuzzer12/FuzzerCrossOver.cpp
deleted file mode 100644
index 83d9f8d47cb..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerCrossOver.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-//===- FuzzerCrossOver.cpp - Cross over two test inputs -------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Cross over test inputs.
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerDefs.h"
-#include "FuzzerMutate.h"
-#include "FuzzerRandom.h"
-#include <cstring>
-
-namespace fuzzer {
-
-// Cross Data1 and Data2, store the result (up to MaxOutSize bytes) in Out.
-size_t MutationDispatcher::CrossOver(const uint8_t *Data1, size_t Size1,
- const uint8_t *Data2, size_t Size2,
- uint8_t *Out, size_t MaxOutSize) {
- assert(Size1 || Size2);
- MaxOutSize = Rand(MaxOutSize) + 1;
- size_t OutPos = 0;
- size_t Pos1 = 0;
- size_t Pos2 = 0;
- size_t *InPos = &Pos1;
- size_t InSize = Size1;
- const uint8_t *Data = Data1;
- bool CurrentlyUsingFirstData = true;
- while (OutPos < MaxOutSize && (Pos1 < Size1 || Pos2 < Size2)) {
- // Merge a part of Data into Out.
- size_t OutSizeLeft = MaxOutSize - OutPos;
- if (*InPos < InSize) {
- size_t InSizeLeft = InSize - *InPos;
- size_t MaxExtraSize = std::min(OutSizeLeft, InSizeLeft);
- size_t ExtraSize = Rand(MaxExtraSize) + 1;
- memcpy(Out + OutPos, Data + *InPos, ExtraSize);
- OutPos += ExtraSize;
- (*InPos) += ExtraSize;
- }
- // Use the other input data on the next iteration.
- InPos = CurrentlyUsingFirstData ? &Pos2 : &Pos1;
- InSize = CurrentlyUsingFirstData ? Size2 : Size1;
- Data = CurrentlyUsingFirstData ? Data2 : Data1;
- CurrentlyUsingFirstData = !CurrentlyUsingFirstData;
- }
- return OutPos;
-}
-
-} // namespace fuzzer
diff --git a/contrib/libs/libfuzzer12/FuzzerDataFlowTrace.cpp b/contrib/libs/libfuzzer12/FuzzerDataFlowTrace.cpp
deleted file mode 100644
index 0e9cdf7e66b..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerDataFlowTrace.cpp
+++ /dev/null
@@ -1,286 +0,0 @@
-//===- FuzzerDataFlowTrace.cpp - DataFlowTrace ---*- 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
-//
-//===----------------------------------------------------------------------===//
-// fuzzer::DataFlowTrace
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerDataFlowTrace.h"
-
-#include "FuzzerCommand.h"
-#include "FuzzerIO.h"
-#include "FuzzerRandom.h"
-#include "FuzzerSHA1.h"
-#include "FuzzerUtil.h"
-
-#include <cstdlib>
-#include <fstream>
-#include <numeric>
-#include <queue>
-#include <sstream>
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-
-namespace fuzzer {
-static const char *kFunctionsTxt = "functions.txt";
-
-bool BlockCoverage::AppendCoverage(const std::string &S) {
- std::stringstream SS(S);
- return AppendCoverage(SS);
-}
-
-// Coverage lines have this form:
-// CN X Y Z T
-// where N is the number of the function, T is the total number of instrumented
-// BBs, and X,Y,Z, if present, are the indecies of covered BB.
-// BB #0, which is the entry block, is not explicitly listed.
-bool BlockCoverage::AppendCoverage(std::istream &IN) {
- std::string L;
- while (std::getline(IN, L, '\n')) {
- if (L.empty())
- continue;
- std::stringstream SS(L.c_str() + 1);
- size_t FunctionId = 0;
- SS >> FunctionId;
- if (L[0] == 'F') {
- FunctionsWithDFT.insert(FunctionId);
- continue;
- }
- if (L[0] != 'C') continue;
- Vector<uint32_t> CoveredBlocks;
- while (true) {
- uint32_t BB = 0;
- SS >> BB;
- if (!SS) break;
- CoveredBlocks.push_back(BB);
- }
- if (CoveredBlocks.empty()) return false;
- uint32_t NumBlocks = CoveredBlocks.back();
- CoveredBlocks.pop_back();
- for (auto BB : CoveredBlocks)
- if (BB >= NumBlocks) return false;
- auto It = Functions.find(FunctionId);
- auto &Counters =
- It == Functions.end()
- ? Functions.insert({FunctionId, Vector<uint32_t>(NumBlocks)})
- .first->second
- : It->second;
-
- if (Counters.size() != NumBlocks) return false; // wrong number of blocks.
-
- Counters[0]++;
- for (auto BB : CoveredBlocks)
- Counters[BB]++;
- }
- return true;
-}
-
-// Assign weights to each function.
-// General principles:
-// * any uncovered function gets weight 0.
-// * a function with lots of uncovered blocks gets bigger weight.
-// * a function with a less frequently executed code gets bigger weight.
-Vector<double> BlockCoverage::FunctionWeights(size_t NumFunctions) const {
- Vector<double> Res(NumFunctions);
- for (auto It : Functions) {
- auto FunctionID = It.first;
- auto Counters = It.second;
- assert(FunctionID < NumFunctions);
- auto &Weight = Res[FunctionID];
- // Give higher weight if the function has a DFT.
- Weight = FunctionsWithDFT.count(FunctionID) ? 1000. : 1;
- // Give higher weight to functions with less frequently seen basic blocks.
- Weight /= SmallestNonZeroCounter(Counters);
- // Give higher weight to functions with the most uncovered basic blocks.
- Weight *= NumberOfUncoveredBlocks(Counters) + 1;
- }
- return Res;
-}
-
-void DataFlowTrace::ReadCoverage(const std::string &DirPath) {
- Vector<SizedFile> Files;
- GetSizedFilesFromDir(DirPath, &Files);
- for (auto &SF : Files) {
- auto Name = Basename(SF.File);
- if (Name == kFunctionsTxt) continue;
- if (!CorporaHashes.count(Name)) continue;
- std::ifstream IF(SF.File);
- Coverage.AppendCoverage(IF);
- }
-}
-
-static void DFTStringAppendToVector(Vector<uint8_t> *DFT,
- const std::string &DFTString) {
- assert(DFT->size() == DFTString.size());
- for (size_t I = 0, Len = DFT->size(); I < Len; I++)
- (*DFT)[I] = DFTString[I] == '1';
-}
-
-// converts a string of '0' and '1' into a Vector<uint8_t>
-static Vector<uint8_t> DFTStringToVector(const std::string &DFTString) {
- Vector<uint8_t> DFT(DFTString.size());
- DFTStringAppendToVector(&DFT, DFTString);
- return DFT;
-}
-
-static bool ParseError(const char *Err, const std::string &Line) {
- Printf("DataFlowTrace: parse error: %s: Line: %s\n", Err, Line.c_str());
- return false;
-}
-
-// TODO(metzman): replace std::string with std::string_view for
-// better performance. Need to figure our how to use string_view on Windows.
-static bool ParseDFTLine(const std::string &Line, size_t *FunctionNum,
- std::string *DFTString) {
- if (!Line.empty() && Line[0] != 'F')
- return false; // Ignore coverage.
- size_t SpacePos = Line.find(' ');
- if (SpacePos == std::string::npos)
- return ParseError("no space in the trace line", Line);
- if (Line.empty() || Line[0] != 'F')
- return ParseError("the trace line doesn't start with 'F'", Line);
- *FunctionNum = std::atol(Line.c_str() + 1);
- const char *Beg = Line.c_str() + SpacePos + 1;
- const char *End = Line.c_str() + Line.size();
- assert(Beg < End);
- size_t Len = End - Beg;
- for (size_t I = 0; I < Len; I++) {
- if (Beg[I] != '0' && Beg[I] != '1')
- return ParseError("the trace should contain only 0 or 1", Line);
- }
- *DFTString = Beg;
- return true;
-}
-
-bool DataFlowTrace::Init(const std::string &DirPath, std::string *FocusFunction,
- Vector<SizedFile> &CorporaFiles, Random &Rand) {
- if (DirPath.empty()) return false;
- Printf("INFO: DataFlowTrace: reading from '%s'\n", DirPath.c_str());
- Vector<SizedFile> Files;
- GetSizedFilesFromDir(DirPath, &Files);
- std::string L;
- size_t FocusFuncIdx = SIZE_MAX;
- Vector<std::string> FunctionNames;
-
- // Collect the hashes of the corpus files.
- for (auto &SF : CorporaFiles)
- CorporaHashes.insert(Hash(FileToVector(SF.File)));
-
- // Read functions.txt
- std::ifstream IF(DirPlusFile(DirPath, kFunctionsTxt));
- size_t NumFunctions = 0;
- while (std::getline(IF, L, '\n')) {
- FunctionNames.push_back(L);
- NumFunctions++;
- if (*FocusFunction == L)
- FocusFuncIdx = NumFunctions - 1;
- }
- if (!NumFunctions)
- return false;
-
- if (*FocusFunction == "auto") {
- // AUTOFOCUS works like this:
- // * reads the coverage data from the DFT files.
- // * assigns weights to functions based on coverage.
- // * chooses a random function according to the weights.
- ReadCoverage(DirPath);
- auto Weights = Coverage.FunctionWeights(NumFunctions);
- Vector<double> Intervals(NumFunctions + 1);
- std::iota(Intervals.begin(), Intervals.end(), 0);
- auto Distribution = std::piecewise_constant_distribution<double>(
- Intervals.begin(), Intervals.end(), Weights.begin());
- FocusFuncIdx = static_cast<size_t>(Distribution(Rand));
- *FocusFunction = FunctionNames[FocusFuncIdx];
- assert(FocusFuncIdx < NumFunctions);
- Printf("INFO: AUTOFOCUS: %zd %s\n", FocusFuncIdx,
- FunctionNames[FocusFuncIdx].c_str());
- for (size_t i = 0; i < NumFunctions; i++) {
- if (!Weights[i]) continue;
- Printf(" [%zd] W %g\tBB-tot %u\tBB-cov %u\tEntryFreq %u:\t%s\n", i,
- Weights[i], Coverage.GetNumberOfBlocks(i),
- Coverage.GetNumberOfCoveredBlocks(i), Coverage.GetCounter(i, 0),
- FunctionNames[i].c_str());
- }
- }
-
- if (!NumFunctions || FocusFuncIdx == SIZE_MAX || Files.size() <= 1)
- return false;
-
- // Read traces.
- size_t NumTraceFiles = 0;
- size_t NumTracesWithFocusFunction = 0;
- for (auto &SF : Files) {
- auto Name = Basename(SF.File);
- if (Name == kFunctionsTxt) continue;
- if (!CorporaHashes.count(Name)) continue; // not in the corpus.
- NumTraceFiles++;
- // Printf("=== %s\n", Name.c_str());
- std::ifstream IF(SF.File);
- while (std::getline(IF, L, '\n')) {
- size_t FunctionNum = 0;
- std::string DFTString;
- if (ParseDFTLine(L, &FunctionNum, &DFTString) &&
- FunctionNum == FocusFuncIdx) {
- NumTracesWithFocusFunction++;
-
- if (FunctionNum >= NumFunctions)
- return ParseError("N is greater than the number of functions", L);
- Traces[Name] = DFTStringToVector(DFTString);
- // Print just a few small traces.
- if (NumTracesWithFocusFunction <= 3 && DFTString.size() <= 16)
- Printf("%s => |%s|\n", Name.c_str(), std::string(DFTString).c_str());
- break; // No need to parse the following lines.
- }
- }
- }
- Printf("INFO: DataFlowTrace: %zd trace files, %zd functions, "
- "%zd traces with focus function\n",
- NumTraceFiles, NumFunctions, NumTracesWithFocusFunction);
- return NumTraceFiles > 0;
-}
-
-int CollectDataFlow(const std::string &DFTBinary, const std::string &DirPath,
- const Vector<SizedFile> &CorporaFiles) {
- Printf("INFO: collecting data flow: bin: %s dir: %s files: %zd\n",
- DFTBinary.c_str(), DirPath.c_str(), CorporaFiles.size());
- if (CorporaFiles.empty()) {
- Printf("ERROR: can't collect data flow without corpus provided.");
- return 1;
- }
-
- static char DFSanEnv[] = "DFSAN_OPTIONS=warn_unimplemented=0";
- putenv(DFSanEnv);
- MkDir(DirPath);
- for (auto &F : CorporaFiles) {
- // For every input F we need to collect the data flow and the coverage.
- // Data flow collection may fail if we request too many DFSan tags at once.
- // So, we start from requesting all tags in range [0,Size) and if that fails
- // we then request tags in [0,Size/2) and [Size/2, Size), and so on.
- // Function number => DFT.
- auto OutPath = DirPlusFile(DirPath, Hash(FileToVector(F.File)));
- std::unordered_map<size_t, Vector<uint8_t>> DFTMap;
- std::unordered_set<std::string> Cov;
- Command Cmd;
- Cmd.addArgument(DFTBinary);
- Cmd.addArgument(F.File);
- Cmd.addArgument(OutPath);
- Printf("CMD: %s\n", Cmd.toString().c_str());
- ExecuteCommand(Cmd);
- }
- // Write functions.txt if it's currently empty or doesn't exist.
- auto FunctionsTxtPath = DirPlusFile(DirPath, kFunctionsTxt);
- if (FileToString(FunctionsTxtPath).empty()) {
- Command Cmd;
- Cmd.addArgument(DFTBinary);
- Cmd.setOutputFile(FunctionsTxtPath);
- ExecuteCommand(Cmd);
- }
- return 0;
-}
-
-} // namespace fuzzer
diff --git a/contrib/libs/libfuzzer12/FuzzerDataFlowTrace.h b/contrib/libs/libfuzzer12/FuzzerDataFlowTrace.h
deleted file mode 100644
index d6e3de30a4e..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerDataFlowTrace.h
+++ /dev/null
@@ -1,135 +0,0 @@
-//===- FuzzerDataFlowTrace.h - Internal header for the Fuzzer ---*- 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
-//
-//===----------------------------------------------------------------------===//
-// fuzzer::DataFlowTrace; reads and handles a data-flow trace.
-//
-// A data flow trace is generated by e.g. dataflow/DataFlow.cpp
-// and is stored on disk in a separate directory.
-//
-// The trace dir contains a file 'functions.txt' which lists function names,
-// oner per line, e.g.
-// ==> functions.txt <==
-// Func2
-// LLVMFuzzerTestOneInput
-// Func1
-//
-// All other files in the dir are the traces, see dataflow/DataFlow.cpp.
-// The name of the file is sha1 of the input used to generate the trace.
-//
-// Current status:
-// the data is parsed and the summary is printed, but the data is not yet
-// used in any other way.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_DATA_FLOW_TRACE
-#define LLVM_FUZZER_DATA_FLOW_TRACE
-
-#include "FuzzerDefs.h"
-#include "FuzzerIO.h"
-
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-#include <string>
-
-namespace fuzzer {
-
-int CollectDataFlow(const std::string &DFTBinary, const std::string &DirPath,
- const Vector<SizedFile> &CorporaFiles);
-
-class BlockCoverage {
- public:
- bool AppendCoverage(std::istream &IN);
- bool AppendCoverage(const std::string &S);
-
- size_t NumCoveredFunctions() const { return Functions.size(); }
-
- uint32_t GetCounter(size_t FunctionId, size_t BasicBlockId) {
- auto It = Functions.find(FunctionId);
- if (It == Functions.end()) return 0;
- const auto &Counters = It->second;
- if (BasicBlockId < Counters.size())
- return Counters[BasicBlockId];
- return 0;
- }
-
- uint32_t GetNumberOfBlocks(size_t FunctionId) {
- auto It = Functions.find(FunctionId);
- if (It == Functions.end()) return 0;
- const auto &Counters = It->second;
- return Counters.size();
- }
-
- uint32_t GetNumberOfCoveredBlocks(size_t FunctionId) {
- auto It = Functions.find(FunctionId);
- if (It == Functions.end()) return 0;
- const auto &Counters = It->second;
- uint32_t Result = 0;
- for (auto Cnt: Counters)
- if (Cnt)
- Result++;
- return Result;
- }
-
- Vector<double> FunctionWeights(size_t NumFunctions) const;
- void clear() { Functions.clear(); }
-
- private:
-
- typedef Vector<uint32_t> CoverageVector;
-
- uint32_t NumberOfCoveredBlocks(const CoverageVector &Counters) const {
- uint32_t Res = 0;
- for (auto Cnt : Counters)
- if (Cnt)
- Res++;
- return Res;
- }
-
- uint32_t NumberOfUncoveredBlocks(const CoverageVector &Counters) const {
- return Counters.size() - NumberOfCoveredBlocks(Counters);
- }
-
- uint32_t SmallestNonZeroCounter(const CoverageVector &Counters) const {
- assert(!Counters.empty());
- uint32_t Res = Counters[0];
- for (auto Cnt : Counters)
- if (Cnt)
- Res = Min(Res, Cnt);
- assert(Res);
- return Res;
- }
-
- // Function ID => vector of counters.
- // Each counter represents how many input files trigger the given basic block.
- std::unordered_map<size_t, CoverageVector> Functions;
- // Functions that have DFT entry.
- std::unordered_set<size_t> FunctionsWithDFT;
-};
-
-class DataFlowTrace {
- public:
- void ReadCoverage(const std::string &DirPath);
- bool Init(const std::string &DirPath, std::string *FocusFunction,
- Vector<SizedFile> &CorporaFiles, Random &Rand);
- void Clear() { Traces.clear(); }
- const Vector<uint8_t> *Get(const std::string &InputSha1) const {
- auto It = Traces.find(InputSha1);
- if (It != Traces.end())
- return &It->second;
- return nullptr;
- }
-
- private:
- // Input's sha1 => DFT for the FocusFunction.
- std::unordered_map<std::string, Vector<uint8_t> > Traces;
- BlockCoverage Coverage;
- std::unordered_set<std::string> CorporaHashes;
-};
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_DATA_FLOW_TRACE
diff --git a/contrib/libs/libfuzzer12/FuzzerDefs.h b/contrib/libs/libfuzzer12/FuzzerDefs.h
deleted file mode 100644
index 1bc89c94488..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerDefs.h
+++ /dev/null
@@ -1,77 +0,0 @@
-//===- FuzzerDefs.h - Internal header for the Fuzzer ------------*- 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
-//
-//===----------------------------------------------------------------------===//
-// Basic definitions.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_DEFS_H
-#define LLVM_FUZZER_DEFS_H
-
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <cstring>
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-
-namespace fuzzer {
-
-template <class T> T Min(T a, T b) { return a < b ? a : b; }
-template <class T> T Max(T a, T b) { return a > b ? a : b; }
-
-class Random;
-class Dictionary;
-class DictionaryEntry;
-class MutationDispatcher;
-struct FuzzingOptions;
-class InputCorpus;
-struct InputInfo;
-struct ExternalFunctions;
-
-// Global interface to functions that may or may not be available.
-extern ExternalFunctions *EF;
-
-// We are using a custom allocator to give a different symbol name to STL
-// containers in order to avoid ODR violations.
-template<typename T>
- class fuzzer_allocator: public std::allocator<T> {
- public:
- fuzzer_allocator() = default;
-
- template<class U>
- fuzzer_allocator(const fuzzer_allocator<U>&) {}
-
- template<class Other>
- struct rebind { typedef fuzzer_allocator<Other> other; };
- };
-
-template<typename T>
-using Vector = std::vector<T, fuzzer_allocator<T>>;
-
-template<typename T>
-using Set = std::set<T, std::less<T>, fuzzer_allocator<T>>;
-
-typedef Vector<uint8_t> Unit;
-typedef Vector<Unit> UnitVector;
-typedef int (*UserCallback)(const uint8_t *Data, size_t Size);
-
-#define exit(status) FuzzerExit(status)
-void FuzzerExit(int status);
-int FuzzerDriver(int *argc, char ***argv, UserCallback Callback);
-
-uint8_t *ExtraCountersBegin();
-uint8_t *ExtraCountersEnd();
-void ClearExtraCounters();
-
-extern bool RunningUserCallback;
-
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_DEFS_H
diff --git a/contrib/libs/libfuzzer12/FuzzerDictionary.h b/contrib/libs/libfuzzer12/FuzzerDictionary.h
deleted file mode 100644
index 301c5d9afec..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerDictionary.h
+++ /dev/null
@@ -1,118 +0,0 @@
-//===- FuzzerDictionary.h - Internal header for the Fuzzer ------*- 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
-//
-//===----------------------------------------------------------------------===//
-// fuzzer::Dictionary
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_DICTIONARY_H
-#define LLVM_FUZZER_DICTIONARY_H
-
-#include "FuzzerDefs.h"
-#include "FuzzerIO.h"
-#include "FuzzerUtil.h"
-#include <algorithm>
-#include <limits>
-
-namespace fuzzer {
-// A simple POD sized array of bytes.
-template <size_t kMaxSizeT> class FixedWord {
-public:
- static const size_t kMaxSize = kMaxSizeT;
- FixedWord() {}
- FixedWord(const uint8_t *B, uint8_t S) { Set(B, S); }
-
- void Set(const uint8_t *B, uint8_t S) {
- assert(S <= kMaxSize);
- memcpy(Data, B, S);
- Size = S;
- }
-
- bool operator==(const FixedWord<kMaxSize> &w) const {
- return Size == w.Size && 0 == memcmp(Data, w.Data, Size);
- }
-
- static size_t GetMaxSize() { return kMaxSize; }
- const uint8_t *data() const { return Data; }
- uint8_t size() const { return Size; }
-
-private:
- uint8_t Size = 0;
- uint8_t Data[kMaxSize];
-};
-
-typedef FixedWord<64> Word;
-
-class DictionaryEntry {
- public:
- DictionaryEntry() {}
- DictionaryEntry(Word W) : W(W) {}
- DictionaryEntry(Word W, size_t PositionHint) : W(W), PositionHint(PositionHint) {}
- const Word &GetW() const { return W; }
-
- bool HasPositionHint() const { return PositionHint != std::numeric_limits<size_t>::max(); }
- size_t GetPositionHint() const {
- assert(HasPositionHint());
- return PositionHint;
- }
- void IncUseCount() { UseCount++; }
- void IncSuccessCount() { SuccessCount++; }
- size_t GetUseCount() const { return UseCount; }
- size_t GetSuccessCount() const {return SuccessCount; }
-
- void Print(const char *PrintAfter = "\n") {
- PrintASCII(W.data(), W.size());
- if (HasPositionHint())
- Printf("@%zd", GetPositionHint());
- Printf("%s", PrintAfter);
- }
-
-private:
- Word W;
- size_t PositionHint = std::numeric_limits<size_t>::max();
- size_t UseCount = 0;
- size_t SuccessCount = 0;
-};
-
-class Dictionary {
- public:
- static const size_t kMaxDictSize = 1 << 14;
-
- bool ContainsWord(const Word &W) const {
- return std::any_of(begin(), end(), [&](const DictionaryEntry &DE) {
- return DE.GetW() == W;
- });
- }
- const DictionaryEntry *begin() const { return &DE[0]; }
- const DictionaryEntry *end() const { return begin() + Size; }
- DictionaryEntry & operator[] (size_t Idx) {
- assert(Idx < Size);
- return DE[Idx];
- }
- void push_back(DictionaryEntry DE) {
- if (Size < kMaxDictSize)
- this->DE[Size++] = DE;
- }
- void clear() { Size = 0; }
- bool empty() const { return Size == 0; }
- size_t size() const { return Size; }
-
-private:
- DictionaryEntry DE[kMaxDictSize];
- size_t Size = 0;
-};
-
-// Parses one dictionary entry.
-// If successful, write the enty to Unit and returns true,
-// otherwise returns false.
-bool ParseOneDictionaryEntry(const std::string &Str, Unit *U);
-// Parses the dictionary file, fills Units, returns true iff all lines
-// were parsed successfully.
-bool ParseDictionaryFile(const std::string &Text, Vector<Unit> *Units);
-
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_DICTIONARY_H
diff --git a/contrib/libs/libfuzzer12/FuzzerDriver.cpp b/contrib/libs/libfuzzer12/FuzzerDriver.cpp
deleted file mode 100644
index 44b8e23cfbf..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerDriver.cpp
+++ /dev/null
@@ -1,933 +0,0 @@
-//===- FuzzerDriver.cpp - FuzzerDriver function and flags -----------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// FuzzerDriver and flag parsing.
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerCommand.h"
-#include "FuzzerCorpus.h"
-#include "FuzzerFork.h"
-#include "FuzzerIO.h"
-#include "FuzzerInterface.h"
-#include "FuzzerInternal.h"
-#include "FuzzerMerge.h"
-#include "FuzzerMutate.h"
-#include "FuzzerPlatform.h"
-#include "FuzzerRandom.h"
-#include "FuzzerTracePC.h"
-#include <algorithm>
-#include <atomic>
-#include <chrono>
-#include <cstdlib>
-#include <cstring>
-#include <mutex>
-#include <string>
-#include <thread>
-#include <fstream>
-
-// This function should be present in the libFuzzer so that the client
-// binary can test for its existence.
-#if LIBFUZZER_MSVC
-extern "C" void __libfuzzer_is_present() {}
-#if defined(_M_IX86) || defined(__i386__)
-#pragma comment(linker, "/include:___libfuzzer_is_present")
-#else
-#pragma comment(linker, "/include:__libfuzzer_is_present")
-#endif
-#else
-extern "C" __attribute__((used)) void __libfuzzer_is_present() {}
-#endif // LIBFUZZER_MSVC
-
-namespace fuzzer {
-
-// Program arguments.
-struct FlagDescription {
- const char *Name;
- const char *Description;
- int Default;
- int *IntFlag;
- const char **StrFlag;
- unsigned int *UIntFlag;
-};
-
-struct {
-#define FUZZER_DEPRECATED_FLAG(Name)
-#define FUZZER_FLAG_INT(Name, Default, Description) int Name;
-#define FUZZER_FLAG_UNSIGNED(Name, Default, Description) unsigned int Name;
-#define FUZZER_FLAG_STRING(Name, Description) const char *Name;
-#include "FuzzerFlags.def"
-#undef FUZZER_DEPRECATED_FLAG
-#undef FUZZER_FLAG_INT
-#undef FUZZER_FLAG_UNSIGNED
-#undef FUZZER_FLAG_STRING
-} Flags;
-
-static const FlagDescription FlagDescriptions [] {
-#define FUZZER_DEPRECATED_FLAG(Name) \
- {#Name, "Deprecated; don't use", 0, nullptr, nullptr, nullptr},
-#define FUZZER_FLAG_INT(Name, Default, Description) \
- {#Name, Description, Default, &Flags.Name, nullptr, nullptr},
-#define FUZZER_FLAG_UNSIGNED(Name, Default, Description) \
- {#Name, Description, static_cast<int>(Default), \
- nullptr, nullptr, &Flags.Name},
-#define FUZZER_FLAG_STRING(Name, Description) \
- {#Name, Description, 0, nullptr, &Flags.Name, nullptr},
-#include "FuzzerFlags.def"
-#undef FUZZER_DEPRECATED_FLAG
-#undef FUZZER_FLAG_INT
-#undef FUZZER_FLAG_UNSIGNED
-#undef FUZZER_FLAG_STRING
-};
-
-static const size_t kNumFlags =
- sizeof(FlagDescriptions) / sizeof(FlagDescriptions[0]);
-
-static Vector<std::string> *Inputs;
-static std::string *ProgName;
-
-static void PrintHelp() {
- Printf("Usage:\n");
- auto Prog = ProgName->c_str();
- Printf("\nTo run fuzzing pass 0 or more directories.\n");
- Printf("%s [-flag1=val1 [-flag2=val2 ...] ] [dir1 [dir2 ...] ]\n", Prog);
-
- Printf("\nTo run individual tests without fuzzing pass 1 or more files:\n");
- Printf("%s [-flag1=val1 [-flag2=val2 ...] ] file1 [file2 ...]\n", Prog);
-
- Printf("\nFlags: (strictly in form -flag=value)\n");
- size_t MaxFlagLen = 0;
- for (size_t F = 0; F < kNumFlags; F++)
- MaxFlagLen = std::max(strlen(FlagDescriptions[F].Name), MaxFlagLen);
-
- for (size_t F = 0; F < kNumFlags; F++) {
- const auto &D = FlagDescriptions[F];
- if (strstr(D.Description, "internal flag") == D.Description) continue;
- Printf(" %s", D.Name);
- for (size_t i = 0, n = MaxFlagLen - strlen(D.Name); i < n; i++)
- Printf(" ");
- Printf("\t");
- Printf("%d\t%s\n", D.Default, D.Description);
- }
- Printf("\nFlags starting with '--' will be ignored and "
- "will be passed verbatim to subprocesses.\n");
-}
-
-static const char *FlagValue(const char *Param, const char *Name) {
- size_t Len = strlen(Name);
- if (Param[0] == '-' && strstr(Param + 1, Name) == Param + 1 &&
- Param[Len + 1] == '=')
- return &Param[Len + 2];
- return nullptr;
-}
-
-// Avoid calling stol as it triggers a bug in clang/glibc build.
-static long MyStol(const char *Str) {
- long Res = 0;
- long Sign = 1;
- if (*Str == '-') {
- Str++;
- Sign = -1;
- }
- for (size_t i = 0; Str[i]; i++) {
- char Ch = Str[i];
- if (Ch < '0' || Ch > '9')
- return Res;
- Res = Res * 10 + (Ch - '0');
- }
- return Res * Sign;
-}
-
-static bool ParseOneFlag(const char *Param) {
- if (Param[0] != '-') return false;
- if (Param[1] == '-') {
- static bool PrintedWarning = false;
- if (!PrintedWarning) {
- PrintedWarning = true;
- Printf("INFO: libFuzzer ignores flags that start with '--'\n");
- }
- for (size_t F = 0; F < kNumFlags; F++)
- if (FlagValue(Param + 1, FlagDescriptions[F].Name))
- Printf("WARNING: did you mean '%s' (single dash)?\n", Param + 1);
- return true;
- }
- for (size_t F = 0; F < kNumFlags; F++) {
- const char *Name = FlagDescriptions[F].Name;
- const char *Str = FlagValue(Param, Name);
- if (Str) {
- if (FlagDescriptions[F].IntFlag) {
- int Val = MyStol(Str);
- *FlagDescriptions[F].IntFlag = Val;
- if (Flags.verbosity >= 2)
- Printf("Flag: %s %d\n", Name, Val);
- return true;
- } else if (FlagDescriptions[F].UIntFlag) {
- unsigned int Val = std::stoul(Str);
- *FlagDescriptions[F].UIntFlag = Val;
- if (Flags.verbosity >= 2)
- Printf("Flag: %s %u\n", Name, Val);
- return true;
- } else if (FlagDescriptions[F].StrFlag) {
- *FlagDescriptions[F].StrFlag = Str;
- if (Flags.verbosity >= 2)
- Printf("Flag: %s %s\n", Name, Str);
- return true;
- } else { // Deprecated flag.
- Printf("Flag: %s: deprecated, don't use\n", Name);
- return true;
- }
- }
- }
- Printf("\n\nWARNING: unrecognized flag '%s'; "
- "use -help=1 to list all flags\n\n", Param);
- return true;
-}
-
-// We don't use any library to minimize dependencies.
-static void ParseFlags(const Vector<std::string> &Args,
- const ExternalFunctions *EF) {
- for (size_t F = 0; F < kNumFlags; F++) {
- if (FlagDescriptions[F].IntFlag)
- *FlagDescriptions[F].IntFlag = FlagDescriptions[F].Default;
- if (FlagDescriptions[F].UIntFlag)
- *FlagDescriptions[F].UIntFlag =
- static_cast<unsigned int>(FlagDescriptions[F].Default);
- if (FlagDescriptions[F].StrFlag)
- *FlagDescriptions[F].StrFlag = nullptr;
- }
-
- // Disable len_control by default, if LLVMFuzzerCustomMutator is used.
- if (EF->LLVMFuzzerCustomMutator) {
- Flags.len_control = 0;
- Printf("INFO: found LLVMFuzzerCustomMutator (%p). "
- "Disabling -len_control by default.\n", EF->LLVMFuzzerCustomMutator);
- }
-
- Inputs = new Vector<std::string>;
- for (size_t A = 1; A < Args.size(); A++) {
- if (ParseOneFlag(Args[A].c_str())) {
- if (Flags.ignore_remaining_args)
- break;
- continue;
- }
- Inputs->push_back(Args[A]);
- }
-}
-
-static std::mutex Mu;
-
-static void PulseThread() {
- while (true) {
- SleepSeconds(600);
- std::lock_guard<std::mutex> Lock(Mu);
- Printf("pulse...\n");
- }
-}
-
-static void WorkerThread(const Command &BaseCmd, std::atomic<unsigned> *Counter,
- unsigned NumJobs, std::atomic<bool> *HasErrors) {
- while (true) {
- unsigned C = (*Counter)++;
- if (C >= NumJobs) break;
- std::string Log = "fuzz-" + std::to_string(C) + ".log";
- Command Cmd(BaseCmd);
- Cmd.setOutputFile(Log);
- Cmd.combineOutAndErr();
- if (Flags.verbosity) {
- std::string CommandLine = Cmd.toString();
- Printf("%s\n", CommandLine.c_str());
- }
- int ExitCode = ExecuteCommand(Cmd);
- if (ExitCode != 0)
- *HasErrors = true;
- std::lock_guard<std::mutex> Lock(Mu);
- Printf("================== Job %u exited with exit code %d ============\n",
- C, ExitCode);
- fuzzer::CopyFileToErr(Log);
- }
-}
-
-static void ValidateDirectoryExists(const std::string &Path,
- bool CreateDirectory) {
- if (Path.empty()) {
- Printf("ERROR: Provided directory path is an empty string\n");
- exit(1);
- }
-
- if (IsDirectory(Path))
- return;
-
- if (CreateDirectory) {
- if (!MkDirRecursive(Path)) {
- Printf("ERROR: Failed to create directory \"%s\"\n", Path.c_str());
- exit(1);
- }
- return;
- }
-
- Printf("ERROR: The required directory \"%s\" does not exist\n", Path.c_str());
- exit(1);
-}
-
-std::string CloneArgsWithoutX(const Vector<std::string> &Args,
- const char *X1, const char *X2) {
- std::string Cmd;
- for (auto &S : Args) {
- if (FlagValue(S.c_str(), X1) || FlagValue(S.c_str(), X2))
- continue;
- Cmd += S + " ";
- }
- return Cmd;
-}
-
-static int RunInMultipleProcesses(const Vector<std::string> &Args,
- unsigned NumWorkers, unsigned NumJobs) {
- std::atomic<unsigned> Counter(0);
- std::atomic<bool> HasErrors(false);
- Command Cmd(Args);
- Cmd.removeFlag("jobs");
- Cmd.removeFlag("workers");
- Vector<std::thread> V;
- std::thread Pulse(PulseThread);
- Pulse.detach();
- for (unsigned i = 0; i < NumWorkers; i++)
- V.push_back(std::thread(WorkerThread, std::ref(Cmd), &Counter, NumJobs, &HasErrors));
- for (auto &T : V)
- T.join();
- return HasErrors ? 1 : 0;
-}
-
-static void RssThread(Fuzzer *F, size_t RssLimitMb) {
- while (true) {
- SleepSeconds(1);
- size_t Peak = GetPeakRSSMb();
- if (Peak > RssLimitMb)
- F->RssLimitCallback();
- }
-}
-
-static void StartRssThread(Fuzzer *F, size_t RssLimitMb) {
- if (!RssLimitMb)
- return;
- std::thread T(RssThread, F, RssLimitMb);
- T.detach();
-}
-
-int RunOneTest(Fuzzer *F, const char *InputFilePath, size_t MaxLen) {
- Unit U = FileToVector(InputFilePath);
- if (MaxLen && MaxLen < U.size())
- U.resize(MaxLen);
- F->ExecuteCallback(U.data(), U.size());
- if (Flags.print_full_coverage) {
- // Leak detection is not needed when collecting full coverage data.
- F->TPCUpdateObservedPCs();
- } else {
- F->TryDetectingAMemoryLeak(U.data(), U.size(), true);
- }
- return 0;
-}
-
-static bool AllInputsAreFiles() {
- if (Inputs->empty()) return false;
- for (auto &Path : *Inputs)
- if (!IsFile(Path))
- return false;
- return true;
-}
-
-static std::string GetDedupTokenFromCmdOutput(const std::string &S) {
- auto Beg = S.find("DEDUP_TOKEN:");
- if (Beg == std::string::npos)
- return "";
- auto End = S.find('\n', Beg);
- if (End == std::string::npos)
- return "";
- return S.substr(Beg, End - Beg);
-}
-
-int CleanseCrashInput(const Vector<std::string> &Args,
- const FuzzingOptions &Options) {
- if (Inputs->size() != 1 || !Flags.exact_artifact_path) {
- Printf("ERROR: -cleanse_crash should be given one input file and"
- " -exact_artifact_path\n");
- exit(1);
- }
- std::string InputFilePath = Inputs->at(0);
- std::string OutputFilePath = Flags.exact_artifact_path;
- Command Cmd(Args);
- Cmd.removeFlag("cleanse_crash");
-
- assert(Cmd.hasArgument(InputFilePath));
- Cmd.removeArgument(InputFilePath);
-
- auto TmpFilePath = TempPath("CleanseCrashInput", ".repro");
- Cmd.addArgument(TmpFilePath);
- Cmd.setOutputFile(getDevNull());
- Cmd.combineOutAndErr();
-
- std::string CurrentFilePath = InputFilePath;
- auto U = FileToVector(CurrentFilePath);
- size_t Size = U.size();
-
- const Vector<uint8_t> ReplacementBytes = {' ', 0xff};
- for (int NumAttempts = 0; NumAttempts < 5; NumAttempts++) {
- bool Changed = false;
- for (size_t Idx = 0; Idx < Size; Idx++) {
- Printf("CLEANSE[%d]: Trying to replace byte %zd of %zd\n", NumAttempts,
- Idx, Size);
- uint8_t OriginalByte = U[Idx];
- if (ReplacementBytes.end() != std::find(ReplacementBytes.begin(),
- ReplacementBytes.end(),
- OriginalByte))
- continue;
- for (auto NewByte : ReplacementBytes) {
- U[Idx] = NewByte;
- WriteToFile(U, TmpFilePath);
- auto ExitCode = ExecuteCommand(Cmd);
- RemoveFile(TmpFilePath);
- if (!ExitCode) {
- U[Idx] = OriginalByte;
- } else {
- Changed = true;
- Printf("CLEANSE: Replaced byte %zd with 0x%x\n", Idx, NewByte);
- WriteToFile(U, OutputFilePath);
- break;
- }
- }
- }
- if (!Changed) break;
- }
- return 0;
-}
-
-int MinimizeCrashInput(const Vector<std::string> &Args,
- const FuzzingOptions &Options) {
- if (Inputs->size() != 1) {
- Printf("ERROR: -minimize_crash should be given one input file\n");
- exit(1);
- }
- std::string InputFilePath = Inputs->at(0);
- Command BaseCmd(Args);
- BaseCmd.removeFlag("minimize_crash");
- BaseCmd.removeFlag("exact_artifact_path");
- assert(BaseCmd.hasArgument(InputFilePath));
- BaseCmd.removeArgument(InputFilePath);
- if (Flags.runs <= 0 && Flags.max_total_time == 0) {
- Printf("INFO: you need to specify -runs=N or "
- "-max_total_time=N with -minimize_crash=1\n"
- "INFO: defaulting to -max_total_time=600\n");
- BaseCmd.addFlag("max_total_time", "600");
- }
-
- BaseCmd.combineOutAndErr();
-
- std::string CurrentFilePath = InputFilePath;
- while (true) {
- Unit U = FileToVector(CurrentFilePath);
- Printf("CRASH_MIN: minimizing crash input: '%s' (%zd bytes)\n",
- CurrentFilePath.c_str(), U.size());
-
- Command Cmd(BaseCmd);
- Cmd.addArgument(CurrentFilePath);
-
- Printf("CRASH_MIN: executing: %s\n", Cmd.toString().c_str());
- std::string CmdOutput;
- bool Success = ExecuteCommand(Cmd, &CmdOutput);
- if (Success) {
- Printf("ERROR: the input %s did not crash\n", CurrentFilePath.c_str());
- exit(1);
- }
- Printf("CRASH_MIN: '%s' (%zd bytes) caused a crash. Will try to minimize "
- "it further\n",
- CurrentFilePath.c_str(), U.size());
- auto DedupToken1 = GetDedupTokenFromCmdOutput(CmdOutput);
- if (!DedupToken1.empty())
- Printf("CRASH_MIN: DedupToken1: %s\n", DedupToken1.c_str());
-
- std::string ArtifactPath =
- Flags.exact_artifact_path
- ? Flags.exact_artifact_path
- : Options.ArtifactPrefix + "minimized-from-" + Hash(U);
- Cmd.addFlag("minimize_crash_internal_step", "1");
- Cmd.addFlag("exact_artifact_path", ArtifactPath);
- Printf("CRASH_MIN: executing: %s\n", Cmd.toString().c_str());
- CmdOutput.clear();
- Success = ExecuteCommand(Cmd, &CmdOutput);
- Printf("%s", CmdOutput.c_str());
- if (Success) {
- if (Flags.exact_artifact_path) {
- CurrentFilePath = Flags.exact_artifact_path;
- WriteToFile(U, CurrentFilePath);
- }
- Printf("CRASH_MIN: failed to minimize beyond %s (%d bytes), exiting\n",
- CurrentFilePath.c_str(), U.size());
- break;
- }
- auto DedupToken2 = GetDedupTokenFromCmdOutput(CmdOutput);
- if (!DedupToken2.empty())
- Printf("CRASH_MIN: DedupToken2: %s\n", DedupToken2.c_str());
-
- if (DedupToken1 != DedupToken2) {
- if (Flags.exact_artifact_path) {
- CurrentFilePath = Flags.exact_artifact_path;
- WriteToFile(U, CurrentFilePath);
- }
- Printf("CRASH_MIN: mismatch in dedup tokens"
- " (looks like a different bug). Won't minimize further\n");
- break;
- }
-
- CurrentFilePath = ArtifactPath;
- Printf("*********************************\n");
- }
- return 0;
-}
-
-int MinimizeCrashInputInternalStep(Fuzzer *F, InputCorpus *Corpus) {
- assert(Inputs->size() == 1);
- std::string InputFilePath = Inputs->at(0);
- Unit U = FileToVector(InputFilePath);
- Printf("INFO: Starting MinimizeCrashInputInternalStep: %zd\n", U.size());
- if (U.size() < 2) {
- Printf("INFO: The input is small enough, exiting\n");
- exit(0);
- }
- F->SetMaxInputLen(U.size());
- F->SetMaxMutationLen(U.size() - 1);
- F->MinimizeCrashLoop(U);
- Printf("INFO: Done MinimizeCrashInputInternalStep, no crashes found\n");
- exit(0);
- return 0;
-}
-
-void Merge(Fuzzer *F, FuzzingOptions &Options, const Vector<std::string> &Args,
- const Vector<std::string> &Corpora, const char *CFPathOrNull) {
- if (Corpora.size() < 2) {
- Printf("INFO: Merge requires two or more corpus dirs\n");
- exit(0);
- }
-
- Vector<SizedFile> OldCorpus, NewCorpus;
- GetSizedFilesFromDir(Corpora[0], &OldCorpus);
- for (size_t i = 1; i < Corpora.size(); i++)
- GetSizedFilesFromDir(Corpora[i], &NewCorpus);
- std::sort(OldCorpus.begin(), OldCorpus.end());
- std::sort(NewCorpus.begin(), NewCorpus.end());
-
- std::string CFPath = CFPathOrNull ? CFPathOrNull : TempPath("Merge", ".txt");
- Vector<std::string> NewFiles;
- Set<uint32_t> NewFeatures, NewCov;
- CrashResistantMerge(Args, OldCorpus, NewCorpus, &NewFiles, {}, &NewFeatures,
- {}, &NewCov, CFPath, true);
- for (auto &Path : NewFiles)
- F->WriteToOutputCorpus(FileToVector(Path, Options.MaxLen));
- // We are done, delete the control file if it was a temporary one.
- if (!Flags.merge_control_file)
- RemoveFile(CFPath);
-
- exit(0);
-}
-
-int AnalyzeDictionary(Fuzzer *F, const Vector<Unit>& Dict,
- UnitVector& Corpus) {
- Printf("Started dictionary minimization (up to %d tests)\n",
- Dict.size() * Corpus.size() * 2);
-
- // Scores and usage count for each dictionary unit.
- Vector<int> Scores(Dict.size());
- Vector<int> Usages(Dict.size());
-
- Vector<size_t> InitialFeatures;
- Vector<size_t> ModifiedFeatures;
- for (auto &C : Corpus) {
- // Get coverage for the testcase without modifications.
- F->ExecuteCallback(C.data(), C.size());
- InitialFeatures.clear();
- TPC.CollectFeatures([&](size_t Feature) {
- InitialFeatures.push_back(Feature);
- });
-
- for (size_t i = 0; i < Dict.size(); ++i) {
- Vector<uint8_t> Data = C;
- auto StartPos = std::search(Data.begin(), Data.end(),
- Dict[i].begin(), Dict[i].end());
- // Skip dictionary unit, if the testcase does not contain it.
- if (StartPos == Data.end())
- continue;
-
- ++Usages[i];
- while (StartPos != Data.end()) {
- // Replace all occurrences of dictionary unit in the testcase.
- auto EndPos = StartPos + Dict[i].size();
- for (auto It = StartPos; It != EndPos; ++It)
- *It ^= 0xFF;
-
- StartPos = std::search(EndPos, Data.end(),
- Dict[i].begin(), Dict[i].end());
- }
-
- // Get coverage for testcase with masked occurrences of dictionary unit.
- F->ExecuteCallback(Data.data(), Data.size());
- ModifiedFeatures.clear();
- TPC.CollectFeatures([&](size_t Feature) {
- ModifiedFeatures.push_back(Feature);
- });
-
- if (InitialFeatures == ModifiedFeatures)
- --Scores[i];
- else
- Scores[i] += 2;
- }
- }
-
- Printf("###### Useless dictionary elements. ######\n");
- for (size_t i = 0; i < Dict.size(); ++i) {
- // Dictionary units with positive score are treated as useful ones.
- if (Scores[i] > 0)
- continue;
-
- Printf("\"");
- PrintASCII(Dict[i].data(), Dict[i].size(), "\"");
- Printf(" # Score: %d, Used: %d\n", Scores[i], Usages[i]);
- }
- Printf("###### End of useless dictionary elements. ######\n");
- return 0;
-}
-
-Vector<std::string> ParseSeedInuts(const char *seed_inputs) {
- // Parse -seed_inputs=file1,file2,... or -seed_inputs=@seed_inputs_file
- Vector<std::string> Files;
- if (!seed_inputs) return Files;
- std::string SeedInputs;
- if (Flags.seed_inputs[0] == '@')
- SeedInputs = FileToString(Flags.seed_inputs + 1); // File contains list.
- else
- SeedInputs = Flags.seed_inputs; // seed_inputs contains the list.
- if (SeedInputs.empty()) {
- Printf("seed_inputs is empty or @file does not exist.\n");
- exit(1);
- }
- // Parse SeedInputs.
- size_t comma_pos = 0;
- while ((comma_pos = SeedInputs.find_last_of(',')) != std::string::npos) {
- Files.push_back(SeedInputs.substr(comma_pos + 1));
- SeedInputs = SeedInputs.substr(0, comma_pos);
- }
- Files.push_back(SeedInputs);
- return Files;
-}
-
-static Vector<SizedFile> ReadCorpora(const Vector<std::string> &CorpusDirs,
- const Vector<std::string> &ExtraSeedFiles) {
- Vector<SizedFile> SizedFiles;
- size_t LastNumFiles = 0;
- for (auto &Dir : CorpusDirs) {
- GetSizedFilesFromDir(Dir, &SizedFiles);
- Printf("INFO: % 8zd files found in %s\n", SizedFiles.size() - LastNumFiles,
- Dir.c_str());
- LastNumFiles = SizedFiles.size();
- }
- for (auto &File : ExtraSeedFiles)
- if (auto Size = FileSize(File))
- SizedFiles.push_back({File, Size});
- return SizedFiles;
-}
-
-void FuzzerExit(int status) {
- if (EF->LLVMFuzzerCleanup)
- EF->LLVMFuzzerCleanup();
- (exit)(status);
-}
-
-int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
- using namespace fuzzer;
- assert(argc && argv && "Argument pointers cannot be nullptr");
- std::string Argv0((*argv)[0]);
- EF = new ExternalFunctions();
- if (EF->LLVMFuzzerInitialize)
- EF->LLVMFuzzerInitialize(argc, argv);
- if (EF->__msan_scoped_disable_interceptor_checks)
- EF->__msan_scoped_disable_interceptor_checks();
- const Vector<std::string> Args(*argv, *argv + *argc);
- assert(!Args.empty());
- ProgName = new std::string(Args[0]);
- if (Argv0 != *ProgName) {
- Printf("ERROR: argv[0] has been modified in LLVMFuzzerInitialize\n");
- exit(1);
- }
- ParseFlags(Args, EF);
- if (Flags.help) {
- PrintHelp();
- return 0;
- }
-
- if (Flags.close_fd_mask & 2)
- DupAndCloseStderr();
- if (Flags.close_fd_mask & 1)
- CloseStdout();
-
- if (Flags.jobs > 0 && Flags.workers == 0) {
- Flags.workers = std::min(NumberOfCpuCores() / 2, Flags.jobs);
- if (Flags.workers > 1)
- Printf("Running %u workers\n", Flags.workers);
- }
-
- if (Flags.workers > 0 && Flags.jobs > 0)
- return RunInMultipleProcesses(Args, Flags.workers, Flags.jobs);
-
- FuzzingOptions Options;
- Options.Verbosity = Flags.verbosity;
- Options.MaxLen = Flags.max_len;
- Options.LenControl = Flags.len_control;
- Options.KeepSeed = Flags.keep_seed;
- Options.UnitTimeoutSec = Flags.timeout;
- Options.ErrorExitCode = Flags.error_exitcode;
- Options.TimeoutExitCode = Flags.timeout_exitcode;
- Options.InterruptExitCode = Flags.interrupted_exitcode;
- Options.DumpInterrupted = Flags.dump_interrupted;
- Options.IgnoreTimeouts = Flags.ignore_timeouts;
- Options.IgnoreOOMs = Flags.ignore_ooms;
- Options.IgnoreCrashes = Flags.ignore_crashes;
- Options.MaxTotalTimeSec = Flags.max_total_time;
- Options.DoCrossOver = Flags.cross_over;
- Options.CrossOverUniformDist = Flags.cross_over_uniform_dist;
- Options.MutateDepth = Flags.mutate_depth;
- Options.ReduceDepth = Flags.reduce_depth;
- Options.UseCounters = Flags.use_counters;
- Options.UseMemmem = Flags.use_memmem;
- Options.UseCmp = Flags.use_cmp;
- Options.UseValueProfile = Flags.use_value_profile;
- Options.Shrink = Flags.shrink;
- Options.ReduceInputs = Flags.reduce_inputs;
- Options.ShuffleAtStartUp = Flags.shuffle;
- Options.PreferSmall = Flags.prefer_small;
- Options.ReloadIntervalSec = Flags.reload;
- Options.OnlyASCII = Flags.only_ascii;
- Options.DetectLeaks = Flags.detect_leaks;
- Options.PurgeAllocatorIntervalSec = Flags.purge_allocator_interval;
- Options.TraceMalloc = Flags.trace_malloc;
- Options.RssLimitMb = Flags.rss_limit_mb;
- Options.MallocLimitMb = Flags.malloc_limit_mb;
- if (!Options.MallocLimitMb)
- Options.MallocLimitMb = Options.RssLimitMb;
- if (Flags.runs >= 0)
- Options.MaxNumberOfRuns = Flags.runs;
- if (!Inputs->empty() && !Flags.minimize_crash_internal_step) {
- // Ensure output corpus assumed to be the first arbitrary argument input
- // is not a path to an existing file.
- std::string OutputCorpusDir = (*Inputs)[0];
- if (!IsFile(OutputCorpusDir)) {
- Options.OutputCorpus = OutputCorpusDir;
- ValidateDirectoryExists(Options.OutputCorpus, Flags.create_missing_dirs);
- }
- }
- Options.ReportSlowUnits = Flags.report_slow_units;
- if (Flags.artifact_prefix) {
- Options.ArtifactPrefix = Flags.artifact_prefix;
-
- // Since the prefix could be a full path to a file name prefix, assume
- // that if the path ends with the platform's separator that a directory
- // is desired
- std::string ArtifactPathDir = Options.ArtifactPrefix;
- if (!IsSeparator(ArtifactPathDir[ArtifactPathDir.length() - 1])) {
- ArtifactPathDir = DirName(ArtifactPathDir);
- }
- ValidateDirectoryExists(ArtifactPathDir, Flags.create_missing_dirs);
- }
- if (Flags.exact_artifact_path) {
- Options.ExactArtifactPath = Flags.exact_artifact_path;
- ValidateDirectoryExists(DirName(Options.ExactArtifactPath),
- Flags.create_missing_dirs);
- }
- Vector<Unit> Dictionary;
- if (Flags.dict)
- if (!ParseDictionaryFile(FileToString(Flags.dict), &Dictionary))
- return 1;
- if (Flags.verbosity > 0 && !Dictionary.empty())
- Printf("Dictionary: %zd entries\n", Dictionary.size());
- bool RunIndividualFiles = AllInputsAreFiles();
- Options.SaveArtifacts =
- !RunIndividualFiles || Flags.minimize_crash_internal_step;
- Options.PrintNewCovPcs = Flags.print_pcs;
- Options.PrintNewCovFuncs = Flags.print_funcs;
- Options.PrintFinalStats = Flags.print_final_stats;
- Options.PrintCorpusStats = Flags.print_corpus_stats;
- Options.PrintCoverage = Flags.print_coverage;
- Options.PrintFullCoverage = Flags.print_full_coverage;
- if (Flags.exit_on_src_pos)
- Options.ExitOnSrcPos = Flags.exit_on_src_pos;
- if (Flags.exit_on_item)
- Options.ExitOnItem = Flags.exit_on_item;
- if (Flags.focus_function)
- Options.FocusFunction = Flags.focus_function;
- if (Flags.data_flow_trace)
- Options.DataFlowTrace = Flags.data_flow_trace;
- if (Flags.features_dir) {
- Options.FeaturesDir = Flags.features_dir;
- ValidateDirectoryExists(Options.FeaturesDir, Flags.create_missing_dirs);
- }
- if (Flags.mutation_graph_file)
- Options.MutationGraphFile = Flags.mutation_graph_file;
- if (Flags.collect_data_flow)
- Options.CollectDataFlow = Flags.collect_data_flow;
- if (Flags.stop_file)
- Options.StopFile = Flags.stop_file;
- Options.Entropic = Flags.entropic;
- Options.EntropicFeatureFrequencyThreshold =
- (size_t)Flags.entropic_feature_frequency_threshold;
- Options.EntropicNumberOfRarestFeatures =
- (size_t)Flags.entropic_number_of_rarest_features;
- Options.EntropicScalePerExecTime = Flags.entropic_scale_per_exec_time;
- if (!Options.FocusFunction.empty())
- Options.Entropic = false; // FocusFunction overrides entropic scheduling.
- if (Options.Entropic)
- Printf("INFO: Running with entropic power schedule (0x%X, %d).\n",
- Options.EntropicFeatureFrequencyThreshold,
- Options.EntropicNumberOfRarestFeatures);
- struct EntropicOptions Entropic;
- Entropic.Enabled = Options.Entropic;
- Entropic.FeatureFrequencyThreshold =
- Options.EntropicFeatureFrequencyThreshold;
- Entropic.NumberOfRarestFeatures = Options.EntropicNumberOfRarestFeatures;
- Entropic.ScalePerExecTime = Options.EntropicScalePerExecTime;
-
- unsigned Seed = Flags.seed;
- // Initialize Seed.
- if (Seed == 0)
- Seed =
- std::chrono::system_clock::now().time_since_epoch().count() + GetPid();
- if (Flags.verbosity)
- Printf("INFO: Seed: %u\n", Seed);
-
- if (Flags.collect_data_flow && !Flags.fork && !Flags.merge) {
- if (RunIndividualFiles)
- return CollectDataFlow(Flags.collect_data_flow, Flags.data_flow_trace,
- ReadCorpora({}, *Inputs));
- else
- return CollectDataFlow(Flags.collect_data_flow, Flags.data_flow_trace,
- ReadCorpora(*Inputs, {}));
- }
-
- Random Rand(Seed);
- auto *MD = new MutationDispatcher(Rand, Options);
- auto *Corpus = new InputCorpus(Options.OutputCorpus, Entropic);
- auto *F = new Fuzzer(Callback, *Corpus, *MD, Options);
-
- for (auto &U: Dictionary)
- if (U.size() <= Word::GetMaxSize())
- MD->AddWordToManualDictionary(Word(U.data(), U.size()));
-
- // Threads are only supported by Chrome. Don't use them with emscripten
- // for now.
-#if !LIBFUZZER_EMSCRIPTEN
- StartRssThread(F, Flags.rss_limit_mb);
-#endif // LIBFUZZER_EMSCRIPTEN
-
- Options.HandleAbrt = Flags.handle_abrt;
- Options.HandleAlrm = !Flags.minimize_crash;
- Options.HandleBus = Flags.handle_bus;
- Options.HandleFpe = Flags.handle_fpe;
- Options.HandleIll = Flags.handle_ill;
- Options.HandleInt = Flags.handle_int;
- Options.HandleSegv = Flags.handle_segv;
- Options.HandleTerm = Flags.handle_term;
- Options.HandleXfsz = Flags.handle_xfsz;
- Options.HandleUsr1 = Flags.handle_usr1;
- Options.HandleUsr2 = Flags.handle_usr2;
- Options.HandleWinExcept = Flags.handle_winexcept;
-
- SetSignalHandler(Options);
-
- std::atexit(Fuzzer::StaticExitCallback);
-
- if (Flags.minimize_crash)
- return MinimizeCrashInput(Args, Options);
-
- if (Flags.minimize_crash_internal_step)
- return MinimizeCrashInputInternalStep(F, Corpus);
-
- if (Flags.cleanse_crash)
- return CleanseCrashInput(Args, Options);
-
- if (RunIndividualFiles) {
- Options.SaveArtifacts = false;
- int Runs = std::max(1, Flags.runs);
- Printf("%s: Running %zd inputs %d time(s) each.\n", ProgName->c_str(),
- Inputs->size(), Runs);
- for (auto &Path : *Inputs) {
- auto StartTime = system_clock::now();
- Printf("Running: %s\n", Path.c_str());
- for (int Iter = 0; Iter < Runs; Iter++)
- RunOneTest(F, Path.c_str(), Options.MaxLen);
- auto StopTime = system_clock::now();
- auto MS = duration_cast<milliseconds>(StopTime - StartTime).count();
- Printf("Executed %s in %zd ms\n", Path.c_str(), (long)MS);
- }
- Printf("***\n"
- "*** NOTE: fuzzing was not performed, you have only\n"
- "*** executed the target code on a fixed set of inputs.\n"
- "***\n");
- F->PrintFinalStats();
- exit(0);
- }
-
- if (Flags.fork)
- FuzzWithFork(F->GetMD().GetRand(), Options, Args, *Inputs, Flags.fork);
-
- if (Flags.merge)
- Merge(F, Options, Args, *Inputs, Flags.merge_control_file);
-
- if (Flags.merge_inner) {
- const size_t kDefaultMaxMergeLen = 1 << 20;
- if (Options.MaxLen == 0)
- F->SetMaxInputLen(kDefaultMaxMergeLen);
- assert(Flags.merge_control_file);
- F->CrashResistantMergeInternalStep(Flags.merge_control_file);
- exit(0);
- }
-
- if (Flags.analyze_dict) {
- size_t MaxLen = INT_MAX; // Large max length.
- UnitVector InitialCorpus;
- for (auto &Inp : *Inputs) {
- Printf("Loading corpus dir: %s\n", Inp.c_str());
- ReadDirToVectorOfUnits(Inp.c_str(), &InitialCorpus, nullptr,
- MaxLen, /*ExitOnError=*/false);
- }
-
- if (Dictionary.empty() || Inputs->empty()) {
- Printf("ERROR: can't analyze dict without dict and corpus provided\n");
- return 1;
- }
- if (AnalyzeDictionary(F, Dictionary, InitialCorpus)) {
- Printf("Dictionary analysis failed\n");
- exit(1);
- }
- Printf("Dictionary analysis succeeded\n");
- exit(0);
- }
-
- auto CorporaFiles = ReadCorpora(*Inputs, ParseSeedInuts(Flags.seed_inputs));
- F->Loop(CorporaFiles);
-
- if (Flags.verbosity)
- Printf("Done %zd runs in %zd second(s)\n", F->getTotalNumberOfRuns(),
- F->secondsSinceProcessStartUp());
- F->PrintFinalStats();
-
- exit(0); // Don't let F destroy itself.
-}
-
-extern "C" ATTRIBUTE_INTERFACE int
-LLVMFuzzerRunDriver(int *argc, char ***argv,
- int (*UserCb)(const uint8_t *Data, size_t Size)) {
- return FuzzerDriver(argc, argv, UserCb);
-}
-
-// Storage for global ExternalFunctions object.
-ExternalFunctions *EF = nullptr;
-
-} // namespace fuzzer
diff --git a/contrib/libs/libfuzzer12/FuzzerExtFunctions.def b/contrib/libs/libfuzzer12/FuzzerExtFunctions.def
deleted file mode 100644
index 40b1e73945f..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerExtFunctions.def
+++ /dev/null
@@ -1,51 +0,0 @@
-//===- FuzzerExtFunctions.def - External functions --------------*- 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 defines the external function pointers that
-// ``fuzzer::ExternalFunctions`` should contain and try to initialize. The
-// EXT_FUNC macro must be defined at the point of inclusion. The signature of
-// the macro is:
-//
-// EXT_FUNC(<name>, <return_type>, <function_signature>, <warn_if_missing>)
-//===----------------------------------------------------------------------===//
-
-// Optional user functions
-EXT_FUNC(LLVMFuzzerInitialize, int, (int *argc, char ***argv), false);
-EXT_FUNC(LLVMFuzzerCleanup, void, (), false);
-EXT_FUNC(LLVMFuzzerCustomMutator, size_t,
- (uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed),
- false);
-EXT_FUNC(LLVMFuzzerCustomCrossOver, size_t,
- (const uint8_t *Data1, size_t Size1,
- const uint8_t *Data2, size_t Size2,
- uint8_t *Out, size_t MaxOutSize, unsigned int Seed),
- false);
-
-// Sanitizer functions
-EXT_FUNC(__lsan_enable, void, (), false);
-EXT_FUNC(__lsan_disable, void, (), false);
-EXT_FUNC(__lsan_do_recoverable_leak_check, int, (), false);
-EXT_FUNC(__sanitizer_acquire_crash_state, int, (), true);
-EXT_FUNC(__sanitizer_install_malloc_and_free_hooks, int,
- (void (*malloc_hook)(const volatile void *, size_t),
- void (*free_hook)(const volatile void *)),
- false);
-EXT_FUNC(__sanitizer_log_write, void, (const char *buf, size_t len), false);
-EXT_FUNC(__sanitizer_purge_allocator, void, (), false);
-EXT_FUNC(__sanitizer_print_memory_profile, void, (size_t, size_t), false);
-EXT_FUNC(__sanitizer_print_stack_trace, void, (), true);
-EXT_FUNC(__sanitizer_symbolize_pc, void,
- (void *, const char *fmt, char *out_buf, size_t out_buf_size), false);
-EXT_FUNC(__sanitizer_get_module_and_offset_for_pc, int,
- (void *pc, char *module_path,
- size_t module_path_len,void **pc_offset), false);
-EXT_FUNC(__sanitizer_set_death_callback, void, (void (*)(void)), true);
-EXT_FUNC(__sanitizer_set_report_fd, void, (void*), false);
-EXT_FUNC(__msan_scoped_disable_interceptor_checks, void, (), false);
-EXT_FUNC(__msan_scoped_enable_interceptor_checks, void, (), false);
-EXT_FUNC(__msan_unpoison, void, (const volatile void *, size_t size), false);
-EXT_FUNC(__msan_unpoison_param, void, (size_t n), false);
diff --git a/contrib/libs/libfuzzer12/FuzzerExtFunctions.h b/contrib/libs/libfuzzer12/FuzzerExtFunctions.h
deleted file mode 100644
index c88aac4e67c..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerExtFunctions.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===- FuzzerExtFunctions.h - Interface to external functions ---*- 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
-//
-//===----------------------------------------------------------------------===//
-// Defines an interface to (possibly optional) functions.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_EXT_FUNCTIONS_H
-#define LLVM_FUZZER_EXT_FUNCTIONS_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-namespace fuzzer {
-
-struct ExternalFunctions {
- // Initialize function pointers. Functions that are not available will be set
- // to nullptr. Do not call this constructor before ``main()`` has been
- // entered.
- ExternalFunctions();
-
-#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
- RETURN_TYPE(*NAME) FUNC_SIG = nullptr
-
-#include "FuzzerExtFunctions.def"
-
-#undef EXT_FUNC
-};
-} // namespace fuzzer
-
-#endif
diff --git a/contrib/libs/libfuzzer12/FuzzerExtFunctionsDlsym.cpp b/contrib/libs/libfuzzer12/FuzzerExtFunctionsDlsym.cpp
deleted file mode 100644
index 95233d2a10d..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerExtFunctionsDlsym.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-//===- FuzzerExtFunctionsDlsym.cpp - Interface to external functions ------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Implementation for operating systems that support dlsym(). We only use it on
-// Apple platforms for now. We don't use this approach on Linux because it
-// requires that clients of LibFuzzer pass ``--export-dynamic`` to the linker.
-// That is a complication we don't wish to expose to clients right now.
-//===----------------------------------------------------------------------===//
-#include "FuzzerPlatform.h"
-#if LIBFUZZER_APPLE
-
-#include "FuzzerExtFunctions.h"
-#include "FuzzerIO.h"
-#include <dlfcn.h>
-
-using namespace fuzzer;
-
-template <typename T>
-static T GetFnPtr(const char *FnName, bool WarnIfMissing) {
- dlerror(); // Clear any previous errors.
- void *Fn = dlsym(RTLD_DEFAULT, FnName);
- if (Fn == nullptr) {
- if (WarnIfMissing) {
- const char *ErrorMsg = dlerror();
- Printf("WARNING: Failed to find function \"%s\".", FnName);
- if (ErrorMsg)
- Printf(" Reason %s.", ErrorMsg);
- Printf("\n");
- }
- }
- return reinterpret_cast<T>(Fn);
-}
-
-namespace fuzzer {
-
-ExternalFunctions::ExternalFunctions() {
-#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
- this->NAME = GetFnPtr<decltype(ExternalFunctions::NAME)>(#NAME, WARN)
-
-#include "FuzzerExtFunctions.def"
-
-#undef EXT_FUNC
-}
-
-} // namespace fuzzer
-
-#endif // LIBFUZZER_APPLE
diff --git a/contrib/libs/libfuzzer12/FuzzerExtFunctionsWeak.cpp b/contrib/libs/libfuzzer12/FuzzerExtFunctionsWeak.cpp
deleted file mode 100644
index 3ef758daa7b..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerExtFunctionsWeak.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//===- FuzzerExtFunctionsWeak.cpp - Interface to external functions -------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Implementation for Linux. This relies on the linker's support for weak
-// symbols. We don't use this approach on Apple platforms because it requires
-// clients of LibFuzzer to pass ``-U _<symbol_name>`` to the linker to allow
-// weak symbols to be undefined. That is a complication we don't want to expose
-// to clients right now.
-//===----------------------------------------------------------------------===//
-#include "FuzzerPlatform.h"
-#if LIBFUZZER_LINUX || LIBFUZZER_NETBSD || LIBFUZZER_FUCHSIA || \
- LIBFUZZER_FREEBSD || LIBFUZZER_EMSCRIPTEN
-
-#include "FuzzerExtFunctions.h"
-#include "FuzzerIO.h"
-
-extern "C" {
-// Declare these symbols as weak to allow them to be optionally defined.
-#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
- __attribute__((weak, visibility("default"))) RETURN_TYPE NAME FUNC_SIG
-
-#include "FuzzerExtFunctions.def"
-
-#undef EXT_FUNC
-}
-
-using namespace fuzzer;
-
-static void CheckFnPtr(void *FnPtr, const char *FnName, bool WarnIfMissing) {
- if (FnPtr == nullptr && WarnIfMissing) {
- Printf("WARNING: Failed to find function \"%s\".\n", FnName);
- }
-}
-
-namespace fuzzer {
-
-ExternalFunctions::ExternalFunctions() {
-#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
- this->NAME = ::NAME; \
- CheckFnPtr(reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(::NAME)), \
- #NAME, WARN);
-
-#include "FuzzerExtFunctions.def"
-
-#undef EXT_FUNC
-}
-
-} // namespace fuzzer
-
-#endif
diff --git a/contrib/libs/libfuzzer12/FuzzerExtFunctionsWindows.cpp b/contrib/libs/libfuzzer12/FuzzerExtFunctionsWindows.cpp
deleted file mode 100644
index 688bad1d51c..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerExtFunctionsWindows.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-//=== FuzzerExtWindows.cpp - Interface to external functions --------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Implementation of FuzzerExtFunctions for Windows. Uses alternatename when
-// compiled with MSVC. Uses weak aliases when compiled with clang. Unfortunately
-// the method each compiler supports is not supported by the other.
-//===----------------------------------------------------------------------===//
-#include "FuzzerPlatform.h"
-#if LIBFUZZER_WINDOWS
-
-#include "FuzzerExtFunctions.h"
-#include "FuzzerIO.h"
-
-using namespace fuzzer;
-
-// Intermediate macro to ensure the parameter is expanded before stringified.
-#define STRINGIFY_(A) #A
-#define STRINGIFY(A) STRINGIFY_(A)
-
-#if LIBFUZZER_MSVC
-// Copied from compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h
-#if defined(_M_IX86) || defined(__i386__)
-#define WIN_SYM_PREFIX "_"
-#else
-#define WIN_SYM_PREFIX
-#endif
-
-// Declare external functions as having alternativenames, so that we can
-// determine if they are not defined.
-#define EXTERNAL_FUNC(Name, Default) \
- __pragma(comment(linker, "/alternatename:" WIN_SYM_PREFIX STRINGIFY( \
- Name) "=" WIN_SYM_PREFIX STRINGIFY(Default)))
-#else
-// Declare external functions as weak to allow them to default to a specified
-// function if not defined explicitly. We must use weak symbols because clang's
-// support for alternatename is not 100%, see
-// https://bugs.llvm.org/show_bug.cgi?id=40218 for more details.
-#define EXTERNAL_FUNC(Name, Default) \
- __attribute__((weak, alias(STRINGIFY(Default))))
-#endif // LIBFUZZER_MSVC
-
-extern "C" {
-#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
- RETURN_TYPE NAME##Def FUNC_SIG { \
- Printf("ERROR: Function \"%s\" not defined.\n", #NAME); \
- exit(1); \
- } \
- EXTERNAL_FUNC(NAME, NAME##Def) RETURN_TYPE NAME FUNC_SIG
-
-#include "FuzzerExtFunctions.def"
-
-#undef EXT_FUNC
-}
-
-template <typename T>
-static T *GetFnPtr(T *Fun, T *FunDef, const char *FnName, bool WarnIfMissing) {
- if (Fun == FunDef) {
- if (WarnIfMissing)
- Printf("WARNING: Failed to find function \"%s\".\n", FnName);
- return nullptr;
- }
- return Fun;
-}
-
-namespace fuzzer {
-
-ExternalFunctions::ExternalFunctions() {
-#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
- this->NAME = GetFnPtr<decltype(::NAME)>(::NAME, ::NAME##Def, #NAME, WARN);
-
-#include "FuzzerExtFunctions.def"
-
-#undef EXT_FUNC
-}
-
-} // namespace fuzzer
-
-#endif // LIBFUZZER_WINDOWS
diff --git a/contrib/libs/libfuzzer12/FuzzerExtraCounters.cpp b/contrib/libs/libfuzzer12/FuzzerExtraCounters.cpp
deleted file mode 100644
index 04f569a1a87..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerExtraCounters.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-//===- FuzzerExtraCounters.cpp - Extra coverage counters ------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Extra coverage counters defined by user code.
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerPlatform.h"
-#include <cstdint>
-
-#if LIBFUZZER_LINUX || LIBFUZZER_NETBSD || LIBFUZZER_FREEBSD || \
- LIBFUZZER_FUCHSIA || LIBFUZZER_EMSCRIPTEN
-__attribute__((weak)) extern uint8_t __start___libfuzzer_extra_counters;
-__attribute__((weak)) extern uint8_t __stop___libfuzzer_extra_counters;
-
-namespace fuzzer {
-uint8_t *ExtraCountersBegin() { return &__start___libfuzzer_extra_counters; }
-uint8_t *ExtraCountersEnd() { return &__stop___libfuzzer_extra_counters; }
-ATTRIBUTE_NO_SANITIZE_ALL
-void ClearExtraCounters() { // hand-written memset, don't asan-ify.
- uintptr_t *Beg = reinterpret_cast<uintptr_t*>(ExtraCountersBegin());
- uintptr_t *End = reinterpret_cast<uintptr_t*>(ExtraCountersEnd());
- for (; Beg < End; Beg++) {
- *Beg = 0;
- __asm__ __volatile__("" : : : "memory");
- }
-}
-
-} // namespace fuzzer
-
-#else
-// TODO: implement for other platforms.
-namespace fuzzer {
-uint8_t *ExtraCountersBegin() { return nullptr; }
-uint8_t *ExtraCountersEnd() { return nullptr; }
-void ClearExtraCounters() {}
-} // namespace fuzzer
-
-#endif
diff --git a/contrib/libs/libfuzzer12/FuzzerFlags.def b/contrib/libs/libfuzzer12/FuzzerFlags.def
deleted file mode 100644
index 078333e81fd..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerFlags.def
+++ /dev/null
@@ -1,205 +0,0 @@
-//===- FuzzerFlags.def - Run-time flags -------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-// Flags. FUZZER_FLAG_INT/FUZZER_FLAG_STRING macros should be defined at the
-// point of inclusion. We are not using any flag parsing library for better
-// portability and independence.
-//===----------------------------------------------------------------------===//
-FUZZER_FLAG_INT(verbosity, 1, "Verbosity level.")
-FUZZER_FLAG_UNSIGNED(seed, 0, "Random seed. If 0, seed is generated.")
-FUZZER_FLAG_INT(runs, -1,
- "Number of individual test runs (-1 for infinite runs).")
-FUZZER_FLAG_INT(max_len, 0, "Maximum length of the test input. "
- "If 0, libFuzzer tries to guess a good value based on the corpus "
- "and reports it. ")
-FUZZER_FLAG_INT(len_control, 100, "Try generating small inputs first, "
- "then try larger inputs over time. Specifies the rate at which the length "
- "limit is increased (smaller == faster). If 0, immediately try inputs with "
- "size up to max_len. Default value is 0, if LLVMFuzzerCustomMutator is used.")
-FUZZER_FLAG_STRING(seed_inputs, "A comma-separated list of input files "
- "to use as an additional seed corpus. Alternatively, an \"@\" followed by "
- "the name of a file containing the comma-separated list.")
-FUZZER_FLAG_INT(keep_seed, 0, "If 1, keep seed inputs in the corpus even if "
- "they do not produce new coverage. When used with |reduce_inputs==1|, the "
- "seed inputs will never be reduced. This option can be useful when seeds are"
- "not properly formed for the fuzz target but still have useful snippets.")
-FUZZER_FLAG_INT(cross_over, 1, "If 1, cross over inputs.")
-FUZZER_FLAG_INT(cross_over_uniform_dist, 0, "Experimental. If 1, use a "
- "uniform probability distribution when choosing inputs to cross over with. "
- "Some of the inputs in the corpus may never get chosen for mutation "
- "depending on the input mutation scheduling policy. With this flag, all "
- "inputs, regardless of the input mutation scheduling policy, can be chosen "
- "as an input to cross over with. This can be particularly useful with "
- "|keep_seed==1|; all the initial seed inputs, even though they do not "
- "increase coverage because they are not properly formed, will still be "
- "chosen as an input to cross over with.")
-
-FUZZER_FLAG_INT(mutate_depth, 5,
- "Apply this number of consecutive mutations to each input.")
-FUZZER_FLAG_INT(reduce_depth, 0, "Experimental/internal. "
- "Reduce depth if mutations lose unique features")
-FUZZER_FLAG_INT(shuffle, 1, "Shuffle inputs at startup")
-FUZZER_FLAG_INT(prefer_small, 1,
- "If 1, always prefer smaller inputs during the corpus shuffle.")
-FUZZER_FLAG_INT(
- timeout, 1200,
- "Timeout in seconds (if positive). "
- "If one unit runs more than this number of seconds the process will abort.")
-FUZZER_FLAG_INT(error_exitcode, 77, "When libFuzzer itself reports a bug "
- "this exit code will be used.")
-FUZZER_FLAG_INT(timeout_exitcode, 70, "When libFuzzer reports a timeout "
- "this exit code will be used.")
-FUZZER_FLAG_INT(interrupted_exitcode, 0, "[arcadia] When libFuzzer intercepts a singal "
- "this exit code will be used.")
-FUZZER_FLAG_INT(dump_interrupted, 0, "[arcadia] If 1, dump current unit on signal.")
-FUZZER_FLAG_INT(max_total_time, 0, "If positive, indicates the maximal total "
- "time in seconds to run the fuzzer.")
-FUZZER_FLAG_INT(help, 0, "Print help.")
-FUZZER_FLAG_INT(fork, 0, "Experimental mode where fuzzing happens "
- "in a subprocess")
-FUZZER_FLAG_INT(ignore_timeouts, 1, "Ignore timeouts in fork mode")
-FUZZER_FLAG_INT(ignore_ooms, 1, "Ignore OOMs in fork mode")
-FUZZER_FLAG_INT(ignore_crashes, 0, "Ignore crashes in fork mode")
-FUZZER_FLAG_INT(merge, 0, "If 1, the 2-nd, 3-rd, etc corpora will be "
- "merged into the 1-st corpus. Only interesting units will be taken. "
- "This flag can be used to minimize a corpus.")
-FUZZER_FLAG_STRING(stop_file, "Stop fuzzing ASAP if this file exists")
-FUZZER_FLAG_STRING(merge_inner, "internal flag")
-FUZZER_FLAG_STRING(merge_control_file,
- "Specify a control file used for the merge process. "
- "If a merge process gets killed it tries to leave this file "
- "in a state suitable for resuming the merge. "
- "By default a temporary file will be used."
- "The same file can be used for multistep merge process.")
-FUZZER_FLAG_INT(minimize_crash, 0, "If 1, minimizes the provided"
- " crash input. Use with -runs=N or -max_total_time=N to limit "
- "the number attempts."
- " Use with -exact_artifact_path to specify the output."
- " Combine with ASAN_OPTIONS=dedup_token_length=3 (or similar) to ensure that"
- " the minimized input triggers the same crash."
- )
-FUZZER_FLAG_INT(cleanse_crash, 0, "If 1, tries to cleanse the provided"
- " crash input to make it contain fewer original bytes."
- " Use with -exact_artifact_path to specify the output."
- )
-FUZZER_FLAG_INT(minimize_crash_internal_step, 0, "internal flag")
-FUZZER_FLAG_STRING(features_dir, "internal flag. Used to dump feature sets on disk."
- "Every time a new input is added to the corpus, a corresponding file in the features_dir"
- " is created containing the unique features of that input."
- " Features are stored in binary format.")
-FUZZER_FLAG_STRING(mutation_graph_file, "Saves a graph (in DOT format) to"
- " mutation_graph_file. The graph contains a vertex for each input that has"
- " unique coverage; directed edges are provided between parents and children"
- " where the child has unique coverage, and are recorded with the type of"
- " mutation that caused the child.")
-FUZZER_FLAG_INT(use_counters, 1, "Use coverage counters")
-FUZZER_FLAG_INT(use_memmem, 1,
- "Use hints from intercepting memmem, strstr, etc")
-FUZZER_FLAG_INT(use_value_profile, 0,
- "Experimental. Use value profile to guide fuzzing.")
-FUZZER_FLAG_INT(use_cmp, 1, "Use CMP traces to guide mutations")
-FUZZER_FLAG_INT(shrink, 0, "Experimental. Try to shrink corpus inputs.")
-FUZZER_FLAG_INT(reduce_inputs, 1,
- "Try to reduce the size of inputs while preserving their full feature sets")
-FUZZER_FLAG_UNSIGNED(jobs, 0, "Number of jobs to run. If jobs >= 1 we spawn"
- " this number of jobs in separate worker processes"
- " with stdout/stderr redirected to fuzz-JOB.log.")
-FUZZER_FLAG_UNSIGNED(workers, 0,
- "Number of simultaneous worker processes to run the jobs."
- " If zero, \"min(jobs,NumberOfCpuCores()/2)\" is used.")
-FUZZER_FLAG_INT(reload, 1,
- "Reload the main corpus every <N> seconds to get new units"
- " discovered by other processes. If 0, disabled")
-FUZZER_FLAG_INT(report_slow_units, 10,
- "Report slowest units if they run for more than this number of seconds.")
-FUZZER_FLAG_INT(only_ascii, 0,
- "If 1, generate only ASCII (isprint+isspace) inputs.")
-FUZZER_FLAG_STRING(dict, "Experimental. Use the dictionary file.")
-FUZZER_FLAG_STRING(artifact_prefix, "Write fuzzing artifacts (crash, "
- "timeout, or slow inputs) as "
- "$(artifact_prefix)file")
-FUZZER_FLAG_STRING(exact_artifact_path,
- "Write the single artifact on failure (crash, timeout) "
- "as $(exact_artifact_path). This overrides -artifact_prefix "
- "and will not use checksum in the file name. Do not "
- "use the same path for several parallel processes.")
-FUZZER_FLAG_INT(print_pcs, 0, "If 1, print out newly covered PCs.")
-FUZZER_FLAG_INT(print_funcs, 2, "If >=1, print out at most this number of "
- "newly covered functions.")
-FUZZER_FLAG_INT(print_final_stats, 0, "If 1, print statistics at exit.")
-FUZZER_FLAG_INT(print_corpus_stats, 0,
- "If 1, print statistics on corpus elements at exit.")
-FUZZER_FLAG_INT(print_coverage, 0, "If 1, print coverage information as text"
- " at exit.")
-FUZZER_FLAG_INT(print_full_coverage, 0, "If 1, print full coverage information "
- "(all branches) as text at exit.")
-FUZZER_FLAG_INT(dump_coverage, 0, "Deprecated.")
-FUZZER_FLAG_INT(handle_segv, 1, "If 1, try to intercept SIGSEGV.")
-FUZZER_FLAG_INT(handle_bus, 1, "If 1, try to intercept SIGBUS.")
-FUZZER_FLAG_INT(handle_abrt, 1, "If 1, try to intercept SIGABRT.")
-FUZZER_FLAG_INT(handle_ill, 1, "If 1, try to intercept SIGILL.")
-FUZZER_FLAG_INT(handle_fpe, 1, "If 1, try to intercept SIGFPE.")
-FUZZER_FLAG_INT(handle_int, 1, "If 1, try to intercept SIGINT.")
-FUZZER_FLAG_INT(handle_term, 1, "If 1, try to intercept SIGTERM.")
-FUZZER_FLAG_INT(handle_xfsz, 1, "If 1, try to intercept SIGXFSZ.")
-FUZZER_FLAG_INT(handle_usr1, 1, "If 1, try to intercept SIGUSR1.")
-FUZZER_FLAG_INT(handle_usr2, 1, "If 1, try to intercept SIGUSR2.")
-FUZZER_FLAG_INT(handle_winexcept, 1, "If 1, try to intercept uncaught Windows "
- "Visual C++ Exceptions.")
-FUZZER_FLAG_INT(close_fd_mask, 0, "If 1, close stdout at startup; "
- "if 2, close stderr; if 3, close both. "
- "Be careful, this will also close e.g. stderr of asan.")
-FUZZER_FLAG_INT(detect_leaks, 1, "If 1, and if LeakSanitizer is enabled "
- "try to detect memory leaks during fuzzing (i.e. not only at shut down).")
-FUZZER_FLAG_INT(purge_allocator_interval, 1, "Purge allocator caches and "
- "quarantines every <N> seconds. When rss_limit_mb is specified (>0), "
- "purging starts when RSS exceeds 50% of rss_limit_mb. Pass "
- "purge_allocator_interval=-1 to disable this functionality.")
-FUZZER_FLAG_INT(trace_malloc, 0, "If >= 1 will print all mallocs/frees. "
- "If >= 2 will also print stack traces.")
-FUZZER_FLAG_INT(rss_limit_mb, 2048, "If non-zero, the fuzzer will exit upon"
- "reaching this limit of RSS memory usage.")
-FUZZER_FLAG_INT(malloc_limit_mb, 0, "If non-zero, the fuzzer will exit "
- "if the target tries to allocate this number of Mb with one malloc call. "
- "If zero (default) same limit as rss_limit_mb is applied.")
-FUZZER_FLAG_STRING(exit_on_src_pos, "Exit if a newly found PC originates"
- " from the given source location. Example: -exit_on_src_pos=foo.cc:123. "
- "Used primarily for testing libFuzzer itself.")
-FUZZER_FLAG_STRING(exit_on_item, "Exit if an item with a given sha1 sum"
- " was added to the corpus. "
- "Used primarily for testing libFuzzer itself.")
-FUZZER_FLAG_INT(ignore_remaining_args, 0, "If 1, ignore all arguments passed "
- "after this one. Useful for fuzzers that need to do their own "
- "argument parsing.")
-FUZZER_FLAG_STRING(focus_function, "Experimental. "
- "Fuzzing will focus on inputs that trigger calls to this function. "
- "If -focus_function=auto and -data_flow_trace is used, libFuzzer "
- "will choose the focus functions automatically. Disables -entropic when "
- "specified.")
-FUZZER_FLAG_INT(entropic, 1, "Enables entropic power schedule.")
-FUZZER_FLAG_INT(entropic_feature_frequency_threshold, 0xFF, "Experimental. If "
- "entropic is enabled, all features which are observed less often than "
- "the specified value are considered as rare.")
-FUZZER_FLAG_INT(entropic_number_of_rarest_features, 100, "Experimental. If "
- "entropic is enabled, we keep track of the frequencies only for the "
- "Top-X least abundant features (union features that are considered as "
- "rare).")
-FUZZER_FLAG_INT(entropic_scale_per_exec_time, 0, "Experimental. If 1, "
- "the Entropic power schedule gets scaled based on the input execution "
- "time. Inputs with lower execution time get scheduled more (up to 30x). "
- "Note that, if 1, fuzzer stops from being deterministic even if a "
- "non-zero random seed is given.")
-
-FUZZER_FLAG_INT(analyze_dict, 0, "Experimental")
-FUZZER_DEPRECATED_FLAG(use_clang_coverage)
-FUZZER_FLAG_STRING(data_flow_trace, "Experimental: use the data flow trace")
-FUZZER_FLAG_STRING(collect_data_flow,
- "Experimental: collect the data flow trace")
-
-FUZZER_FLAG_INT(create_missing_dirs, 0, "Automatically attempt to create "
- "directories for arguments that would normally expect them to already "
- "exist (i.e. artifact_prefix, exact_artifact_path, features_dir, corpus)")
diff --git a/contrib/libs/libfuzzer12/FuzzerFork.cpp b/contrib/libs/libfuzzer12/FuzzerFork.cpp
deleted file mode 100644
index 84725d22a9c..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerFork.cpp
+++ /dev/null
@@ -1,413 +0,0 @@
-//===- FuzzerFork.cpp - run fuzzing in separate subprocesses --------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Spawn and orchestrate separate fuzzing processes.
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerCommand.h"
-#include "FuzzerFork.h"
-#include "FuzzerIO.h"
-#include "FuzzerInternal.h"
-#include "FuzzerMerge.h"
-#include "FuzzerSHA1.h"
-#include "FuzzerTracePC.h"
-#include "FuzzerUtil.h"
-
-#include <atomic>
-#include <chrono>
-#include <condition_variable>
-#include <fstream>
-#include <memory>
-#include <mutex>
-#include <queue>
-#include <sstream>
-#include <thread>
-
-namespace fuzzer {
-
-struct Stats {
- size_t number_of_executed_units = 0;
- size_t peak_rss_mb = 0;
- size_t average_exec_per_sec = 0;
-};
-
-static Stats ParseFinalStatsFromLog(const std::string &LogPath) {
- std::ifstream In(LogPath);
- std::string Line;
- Stats Res;
- struct {
- const char *Name;
- size_t *Var;
- } NameVarPairs[] = {
- {"stat::number_of_executed_units:", &Res.number_of_executed_units},
- {"stat::peak_rss_mb:", &Res.peak_rss_mb},
- {"stat::average_exec_per_sec:", &Res.average_exec_per_sec},
- {nullptr, nullptr},
- };
- while (std::getline(In, Line, '\n')) {
- if (Line.find("stat::") != 0) continue;
- std::istringstream ISS(Line);
- std::string Name;
- size_t Val;
- ISS >> Name >> Val;
- for (size_t i = 0; NameVarPairs[i].Name; i++)
- if (Name == NameVarPairs[i].Name)
- *NameVarPairs[i].Var = Val;
- }
- return Res;
-}
-
-struct FuzzJob {
- // Inputs.
- Command Cmd;
- std::string CorpusDir;
- std::string FeaturesDir;
- std::string LogPath;
- std::string SeedListPath;
- std::string CFPath;
- size_t JobId;
-
- int DftTimeInSeconds = 0;
-
- // Fuzzing Outputs.
- int ExitCode;
-
- ~FuzzJob() {
- RemoveFile(CFPath);
- RemoveFile(LogPath);
- RemoveFile(SeedListPath);
- RmDirRecursive(CorpusDir);
- RmDirRecursive(FeaturesDir);
- }
-};
-
-struct GlobalEnv {
- Vector<std::string> Args;
- Vector<std::string> CorpusDirs;
- std::string MainCorpusDir;
- std::string TempDir;
- std::string DFTDir;
- std::string DataFlowBinary;
- Set<uint32_t> Features, Cov;
- Set<std::string> FilesWithDFT;
- Vector<std::string> Files;
- Random *Rand;
- std::chrono::system_clock::time_point ProcessStartTime;
- int Verbosity = 0;
-
- size_t NumTimeouts = 0;
- size_t NumOOMs = 0;
- size_t NumCrashes = 0;
-
-
- size_t NumRuns = 0;
-
- std::string StopFile() { return DirPlusFile(TempDir, "STOP"); }
-
- size_t secondsSinceProcessStartUp() const {
- return std::chrono::duration_cast<std::chrono::seconds>(
- std::chrono::system_clock::now() - ProcessStartTime)
- .count();
- }
-
- FuzzJob *CreateNewJob(size_t JobId) {
- Command Cmd(Args);
- Cmd.removeFlag("fork");
- Cmd.removeFlag("runs");
- Cmd.removeFlag("collect_data_flow");
- for (auto &C : CorpusDirs) // Remove all corpora from the args.
- Cmd.removeArgument(C);
- Cmd.addFlag("reload", "0"); // working in an isolated dir, no reload.
- Cmd.addFlag("print_final_stats", "1");
- Cmd.addFlag("print_funcs", "0"); // no need to spend time symbolizing.
- Cmd.addFlag("max_total_time", std::to_string(std::min((size_t)300, JobId)));
- Cmd.addFlag("stop_file", StopFile());
- if (!DataFlowBinary.empty()) {
- Cmd.addFlag("data_flow_trace", DFTDir);
- if (!Cmd.hasFlag("focus_function"))
- Cmd.addFlag("focus_function", "auto");
- }
- auto Job = new FuzzJob;
- std::string Seeds;
- if (size_t CorpusSubsetSize =
- std::min(Files.size(), (size_t)sqrt(Files.size() + 2))) {
- auto Time1 = std::chrono::system_clock::now();
- for (size_t i = 0; i < CorpusSubsetSize; i++) {
- auto &SF = Files[Rand->SkewTowardsLast(Files.size())];
- Seeds += (Seeds.empty() ? "" : ",") + SF;
- CollectDFT(SF);
- }
- auto Time2 = std::chrono::system_clock::now();
- Job->DftTimeInSeconds = duration_cast<seconds>(Time2 - Time1).count();
- }
- if (!Seeds.empty()) {
- Job->SeedListPath =
- DirPlusFile(TempDir, std::to_string(JobId) + ".seeds");
- WriteToFile(Seeds, Job->SeedListPath);
- Cmd.addFlag("seed_inputs", "@" + Job->SeedListPath);
- }
- Job->LogPath = DirPlusFile(TempDir, std::to_string(JobId) + ".log");
- Job->CorpusDir = DirPlusFile(TempDir, "C" + std::to_string(JobId));
- Job->FeaturesDir = DirPlusFile(TempDir, "F" + std::to_string(JobId));
- Job->CFPath = DirPlusFile(TempDir, std::to_string(JobId) + ".merge");
- Job->JobId = JobId;
-
-
- Cmd.addArgument(Job->CorpusDir);
- Cmd.addFlag("features_dir", Job->FeaturesDir);
-
- for (auto &D : {Job->CorpusDir, Job->FeaturesDir}) {
- RmDirRecursive(D);
- MkDir(D);
- }
-
- Cmd.setOutputFile(Job->LogPath);
- Cmd.combineOutAndErr();
-
- Job->Cmd = Cmd;
-
- if (Verbosity >= 2)
- Printf("Job %zd/%p Created: %s\n", JobId, Job,
- Job->Cmd.toString().c_str());
- // Start from very short runs and gradually increase them.
- return Job;
- }
-
- void RunOneMergeJob(FuzzJob *Job) {
- auto Stats = ParseFinalStatsFromLog(Job->LogPath);
- NumRuns += Stats.number_of_executed_units;
-
- Vector<SizedFile> TempFiles, MergeCandidates;
- // Read all newly created inputs and their feature sets.
- // Choose only those inputs that have new features.
- GetSizedFilesFromDir(Job->CorpusDir, &TempFiles);
- std::sort(TempFiles.begin(), TempFiles.end());
- for (auto &F : TempFiles) {
- auto FeatureFile = F.File;
- FeatureFile.replace(0, Job->CorpusDir.size(), Job->FeaturesDir);
- auto FeatureBytes = FileToVector(FeatureFile, 0, false);
- assert((FeatureBytes.size() % sizeof(uint32_t)) == 0);
- Vector<uint32_t> NewFeatures(FeatureBytes.size() / sizeof(uint32_t));
- memcpy(NewFeatures.data(), FeatureBytes.data(), FeatureBytes.size());
- for (auto Ft : NewFeatures) {
- if (!Features.count(Ft)) {
- MergeCandidates.push_back(F);
- break;
- }
- }
- }
- // if (!FilesToAdd.empty() || Job->ExitCode != 0)
- Printf("#%zd: cov: %zd ft: %zd corp: %zd exec/s %zd "
- "oom/timeout/crash: %zd/%zd/%zd time: %zds job: %zd dft_time: %d\n",
- NumRuns, Cov.size(), Features.size(), Files.size(),
- Stats.average_exec_per_sec, NumOOMs, NumTimeouts, NumCrashes,
- secondsSinceProcessStartUp(), Job->JobId, Job->DftTimeInSeconds);
-
- if (MergeCandidates.empty()) return;
-
- Vector<std::string> FilesToAdd;
- Set<uint32_t> NewFeatures, NewCov;
- CrashResistantMerge(Args, {}, MergeCandidates, &FilesToAdd, Features,
- &NewFeatures, Cov, &NewCov, Job->CFPath, false);
- for (auto &Path : FilesToAdd) {
- auto U = FileToVector(Path);
- auto NewPath = DirPlusFile(MainCorpusDir, Hash(U));
- WriteToFile(U, NewPath);
- Files.push_back(NewPath);
- }
- Features.insert(NewFeatures.begin(), NewFeatures.end());
- Cov.insert(NewCov.begin(), NewCov.end());
- for (auto Idx : NewCov)
- if (auto *TE = TPC.PCTableEntryByIdx(Idx))
- if (TPC.PcIsFuncEntry(TE))
- PrintPC(" NEW_FUNC: %p %F %L\n", "",
- TPC.GetNextInstructionPc(TE->PC));
-
- }
-
-
- void CollectDFT(const std::string &InputPath) {
- if (DataFlowBinary.empty()) return;
- if (!FilesWithDFT.insert(InputPath).second) return;
- Command Cmd(Args);
- Cmd.removeFlag("fork");
- Cmd.removeFlag("runs");
- Cmd.addFlag("data_flow_trace", DFTDir);
- Cmd.addArgument(InputPath);
- for (auto &C : CorpusDirs) // Remove all corpora from the args.
- Cmd.removeArgument(C);
- Cmd.setOutputFile(DirPlusFile(TempDir, "dft.log"));
- Cmd.combineOutAndErr();
- // Printf("CollectDFT: %s\n", Cmd.toString().c_str());
- ExecuteCommand(Cmd);
- }
-
-};
-
-struct JobQueue {
- std::queue<FuzzJob *> Qu;
- std::mutex Mu;
- std::condition_variable Cv;
-
- void Push(FuzzJob *Job) {
- {
- std::lock_guard<std::mutex> Lock(Mu);
- Qu.push(Job);
- }
- Cv.notify_one();
- }
- FuzzJob *Pop() {
- std::unique_lock<std::mutex> Lk(Mu);
- // std::lock_guard<std::mutex> Lock(Mu);
- Cv.wait(Lk, [&]{return !Qu.empty();});
- assert(!Qu.empty());
- auto Job = Qu.front();
- Qu.pop();
- return Job;
- }
-};
-
-void WorkerThread(JobQueue *FuzzQ, JobQueue *MergeQ) {
- while (auto Job = FuzzQ->Pop()) {
- // Printf("WorkerThread: job %p\n", Job);
- Job->ExitCode = ExecuteCommand(Job->Cmd);
- MergeQ->Push(Job);
- }
-}
-
-// This is just a skeleton of an experimental -fork=1 feature.
-void FuzzWithFork(Random &Rand, const FuzzingOptions &Options,
- const Vector<std::string> &Args,
- const Vector<std::string> &CorpusDirs, int NumJobs) {
- Printf("INFO: -fork=%d: fuzzing in separate process(s)\n", NumJobs);
-
- GlobalEnv Env;
- Env.Args = Args;
- Env.CorpusDirs = CorpusDirs;
- Env.Rand = &Rand;
- Env.Verbosity = Options.Verbosity;
- Env.ProcessStartTime = std::chrono::system_clock::now();
- Env.DataFlowBinary = Options.CollectDataFlow;
-
- Vector<SizedFile> SeedFiles;
- for (auto &Dir : CorpusDirs)
- GetSizedFilesFromDir(Dir, &SeedFiles);
- std::sort(SeedFiles.begin(), SeedFiles.end());
- Env.TempDir = TempPath("FuzzWithFork", ".dir");
- Env.DFTDir = DirPlusFile(Env.TempDir, "DFT");
- RmDirRecursive(Env.TempDir); // in case there is a leftover from old runs.
- MkDir(Env.TempDir);
- MkDir(Env.DFTDir);
-
-
- if (CorpusDirs.empty())
- MkDir(Env.MainCorpusDir = DirPlusFile(Env.TempDir, "C"));
- else
- Env.MainCorpusDir = CorpusDirs[0];
-
- if (Options.KeepSeed) {
- for (auto &File : SeedFiles)
- Env.Files.push_back(File.File);
- } else {
- auto CFPath = DirPlusFile(Env.TempDir, "merge.txt");
- CrashResistantMerge(Env.Args, {}, SeedFiles, &Env.Files, {}, &Env.Features,
- {}, &Env.Cov, CFPath, false);
- RemoveFile(CFPath);
- }
- Printf("INFO: -fork=%d: %zd seed inputs, starting to fuzz in %s\n", NumJobs,
- Env.Files.size(), Env.TempDir.c_str());
-
- int ExitCode = 0;
-
- JobQueue FuzzQ, MergeQ;
-
- auto StopJobs = [&]() {
- for (int i = 0; i < NumJobs; i++)
- FuzzQ.Push(nullptr);
- MergeQ.Push(nullptr);
- WriteToFile(Unit({1}), Env.StopFile());
- };
-
- size_t JobId = 1;
- Vector<std::thread> Threads;
- for (int t = 0; t < NumJobs; t++) {
- Threads.push_back(std::thread(WorkerThread, &FuzzQ, &MergeQ));
- FuzzQ.Push(Env.CreateNewJob(JobId++));
- }
-
- while (true) {
- std::unique_ptr<FuzzJob> Job(MergeQ.Pop());
- if (!Job)
- break;
- ExitCode = Job->ExitCode;
- if (ExitCode == Options.InterruptExitCode) {
- Printf("==%lu== libFuzzer: a child was interrupted; exiting\n", GetPid());
- StopJobs();
- break;
- }
- Fuzzer::MaybeExitGracefully();
-
- Env.RunOneMergeJob(Job.get());
-
- // Continue if our crash is one of the ignorred ones.
- if (Options.IgnoreTimeouts && ExitCode == Options.TimeoutExitCode)
- Env.NumTimeouts++;
- else if (Options.IgnoreOOMs && ExitCode == Options.OOMExitCode)
- Env.NumOOMs++;
- else if (ExitCode != 0) {
- Env.NumCrashes++;
- if (Options.IgnoreCrashes) {
- std::ifstream In(Job->LogPath);
- std::string Line;
- while (std::getline(In, Line, '\n'))
- if (Line.find("ERROR:") != Line.npos ||
- Line.find("runtime error:") != Line.npos)
- Printf("%s\n", Line.c_str());
- } else {
- // And exit if we don't ignore this crash.
- Printf("INFO: log from the inner process:\n%s",
- FileToString(Job->LogPath).c_str());
- StopJobs();
- break;
- }
- }
-
- // Stop if we are over the time budget.
- // This is not precise, since other threads are still running
- // and we will wait while joining them.
- // We also don't stop instantly: other jobs need to finish.
- if (Options.MaxTotalTimeSec > 0 &&
- Env.secondsSinceProcessStartUp() >= (size_t)Options.MaxTotalTimeSec) {
- Printf("INFO: fuzzed for %zd seconds, wrapping up soon\n",
- Env.secondsSinceProcessStartUp());
- StopJobs();
- break;
- }
- if (Env.NumRuns >= Options.MaxNumberOfRuns) {
- Printf("INFO: fuzzed for %zd iterations, wrapping up soon\n",
- Env.NumRuns);
- StopJobs();
- break;
- }
-
- FuzzQ.Push(Env.CreateNewJob(JobId++));
- }
-
- for (auto &T : Threads)
- T.join();
-
- // The workers have terminated. Don't try to remove the directory before they
- // terminate to avoid a race condition preventing cleanup on Windows.
- RmDirRecursive(Env.TempDir);
-
- // Use the exit code from the last child process.
- Printf("INFO: exiting: %d time: %zds\n", ExitCode,
- Env.secondsSinceProcessStartUp());
- exit(ExitCode);
-}
-
-} // namespace fuzzer
diff --git a/contrib/libs/libfuzzer12/FuzzerFork.h b/contrib/libs/libfuzzer12/FuzzerFork.h
deleted file mode 100644
index b29a43e13fb..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerFork.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//===- FuzzerFork.h - run fuzzing in sub-processes --------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_FORK_H
-#define LLVM_FUZZER_FORK_H
-
-#include "FuzzerDefs.h"
-#include "FuzzerOptions.h"
-#include "FuzzerRandom.h"
-
-#include <string>
-
-namespace fuzzer {
-void FuzzWithFork(Random &Rand, const FuzzingOptions &Options,
- const Vector<std::string> &Args,
- const Vector<std::string> &CorpusDirs, int NumJobs);
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_FORK_H
diff --git a/contrib/libs/libfuzzer12/FuzzerIO.cpp b/contrib/libs/libfuzzer12/FuzzerIO.cpp
deleted file mode 100644
index 54a7219fc0e..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerIO.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-//===- FuzzerIO.cpp - IO utils. -------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// IO functions.
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerDefs.h"
-#include "FuzzerExtFunctions.h"
-#include "FuzzerIO.h"
-#include "FuzzerUtil.h"
-#include <algorithm>
-#include <cstdarg>
-#include <fstream>
-#include <iterator>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-namespace fuzzer {
-
-static FILE *OutputFile = stderr;
-
-long GetEpoch(const std::string &Path) {
- struct stat St;
- if (stat(Path.c_str(), &St))
- return 0; // Can't stat, be conservative.
- return St.st_mtime;
-}
-
-Unit FileToVector(const std::string &Path, size_t MaxSize, bool ExitOnError) {
- std::ifstream T(Path, std::ios::binary);
- if (ExitOnError && !T) {
- Printf("No such directory: %s; exiting\n", Path.c_str());
- exit(1);
- }
-
- T.seekg(0, T.end);
- auto EndPos = T.tellg();
- if (EndPos < 0) return {};
- size_t FileLen = EndPos;
- if (MaxSize)
- FileLen = std::min(FileLen, MaxSize);
-
- T.seekg(0, T.beg);
- Unit Res(FileLen);
- T.read(reinterpret_cast<char *>(Res.data()), FileLen);
- return Res;
-}
-
-std::string FileToString(const std::string &Path) {
- std::ifstream T(Path, std::ios::binary);
- return std::string((std::istreambuf_iterator<char>(T)),
- std::istreambuf_iterator<char>());
-}
-
-void CopyFileToErr(const std::string &Path) {
- Printf("%s", FileToString(Path).c_str());
-}
-
-void WriteToFile(const Unit &U, const std::string &Path) {
- WriteToFile(U.data(), U.size(), Path);
-}
-
-void WriteToFile(const std::string &Data, const std::string &Path) {
- WriteToFile(reinterpret_cast<const uint8_t *>(Data.c_str()), Data.size(),
- Path);
-}
-
-void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path) {
- // Use raw C interface because this function may be called from a sig handler.
- FILE *Out = fopen(Path.c_str(), "wb");
- if (!Out) return;
- fwrite(Data, sizeof(Data[0]), Size, Out);
- fclose(Out);
-}
-
-void AppendToFile(const std::string &Data, const std::string &Path) {
- AppendToFile(reinterpret_cast<const uint8_t *>(Data.data()), Data.size(),
- Path);
-}
-
-void AppendToFile(const uint8_t *Data, size_t Size, const std::string &Path) {
- FILE *Out = fopen(Path.c_str(), "a");
- if (!Out)
- return;
- fwrite(Data, sizeof(Data[0]), Size, Out);
- fclose(Out);
-}
-
-void ReadDirToVectorOfUnits(const char *Path, Vector<Unit> *V,
- long *Epoch, size_t MaxSize, bool ExitOnError) {
- long E = Epoch ? *Epoch : 0;
- Vector<std::string> Files;
- ListFilesInDirRecursive(Path, Epoch, &Files, /*TopDir*/true);
- size_t NumLoaded = 0;
- for (size_t i = 0; i < Files.size(); i++) {
- auto &X = Files[i];
- if (Epoch && GetEpoch(X) < E) continue;
- NumLoaded++;
- if ((NumLoaded & (NumLoaded - 1)) == 0 && NumLoaded >= 1024)
- Printf("Loaded %zd/%zd files from %s\n", NumLoaded, Files.size(), Path);
- auto S = FileToVector(X, MaxSize, ExitOnError);
- if (!S.empty())
- V->push_back(S);
- }
-}
-
-
-void GetSizedFilesFromDir(const std::string &Dir, Vector<SizedFile> *V) {
- Vector<std::string> Files;
- ListFilesInDirRecursive(Dir, 0, &Files, /*TopDir*/true);
- for (auto &File : Files)
- if (size_t Size = FileSize(File))
- V->push_back({File, Size});
-}
-
-std::string DirPlusFile(const std::string &DirPath,
- const std::string &FileName) {
- return DirPath + GetSeparator() + FileName;
-}
-
-void DupAndCloseStderr() {
- int OutputFd = DuplicateFile(2);
- if (OutputFd >= 0) {
- FILE *NewOutputFile = OpenFile(OutputFd, "w");
- if (NewOutputFile) {
- OutputFile = NewOutputFile;
- if (EF->__sanitizer_set_report_fd)
- EF->__sanitizer_set_report_fd(
- reinterpret_cast<void *>(GetHandleFromFd(OutputFd)));
- DiscardOutput(2);
- }
- }
-}
-
-void CloseStdout() {
- DiscardOutput(1);
-}
-
-void Printf(const char *Fmt, ...) {
- va_list ap;
- va_start(ap, Fmt);
- vfprintf(OutputFile, Fmt, ap);
- va_end(ap);
- fflush(OutputFile);
-}
-
-void VPrintf(bool Verbose, const char *Fmt, ...) {
- if (!Verbose) return;
- va_list ap;
- va_start(ap, Fmt);
- vfprintf(OutputFile, Fmt, ap);
- va_end(ap);
- fflush(OutputFile);
-}
-
-static bool MkDirRecursiveInner(const std::string &Leaf) {
- // Prevent chance of potential infinite recursion
- if (Leaf == ".")
- return true;
-
- const std::string &Dir = DirName(Leaf);
-
- if (IsDirectory(Dir)) {
- MkDir(Leaf);
- return IsDirectory(Leaf);
- }
-
- bool ret = MkDirRecursiveInner(Dir);
- if (!ret) {
- // Give up early if a previous MkDir failed
- return ret;
- }
-
- MkDir(Leaf);
- return IsDirectory(Leaf);
-}
-
-bool MkDirRecursive(const std::string &Dir) {
- if (Dir.empty())
- return false;
-
- if (IsDirectory(Dir))
- return true;
-
- return MkDirRecursiveInner(Dir);
-}
-
-void RmDirRecursive(const std::string &Dir) {
- IterateDirRecursive(
- Dir, [](const std::string &Path) {},
- [](const std::string &Path) { RmDir(Path); },
- [](const std::string &Path) { RemoveFile(Path); });
-}
-
-std::string TempPath(const char *Prefix, const char *Extension) {
- return DirPlusFile(TmpDir(), std::string("libFuzzerTemp.") + Prefix +
- std::to_string(GetPid()) + Extension);
-}
-
-} // namespace fuzzer
diff --git a/contrib/libs/libfuzzer12/FuzzerIO.h b/contrib/libs/libfuzzer12/FuzzerIO.h
deleted file mode 100644
index abd25110d07..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerIO.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//===- FuzzerIO.h - Internal header for IO utils ----------------*- 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
-//
-//===----------------------------------------------------------------------===//
-// IO interface.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_IO_H
-#define LLVM_FUZZER_IO_H
-
-#include "FuzzerDefs.h"
-
-namespace fuzzer {
-
-long GetEpoch(const std::string &Path);
-
-Unit FileToVector(const std::string &Path, size_t MaxSize = 0,
- bool ExitOnError = true);
-
-std::string FileToString(const std::string &Path);
-
-void CopyFileToErr(const std::string &Path);
-
-void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path);
-// Write Data.c_str() to the file without terminating null character.
-void WriteToFile(const std::string &Data, const std::string &Path);
-void WriteToFile(const Unit &U, const std::string &Path);
-
-void AppendToFile(const uint8_t *Data, size_t Size, const std::string &Path);
-void AppendToFile(const std::string &Data, const std::string &Path);
-
-void ReadDirToVectorOfUnits(const char *Path, Vector<Unit> *V,
- long *Epoch, size_t MaxSize, bool ExitOnError);
-
-// Returns "Dir/FileName" or equivalent for the current OS.
-std::string DirPlusFile(const std::string &DirPath,
- const std::string &FileName);
-
-// Returns the name of the dir, similar to the 'dirname' utility.
-std::string DirName(const std::string &FileName);
-
-// Returns path to a TmpDir.
-std::string TmpDir();
-
-std::string TempPath(const char *Prefix, const char *Extension);
-
-bool IsInterestingCoverageFile(const std::string &FileName);
-
-void DupAndCloseStderr();
-
-void CloseStdout();
-
-void Printf(const char *Fmt, ...);
-void VPrintf(bool Verbose, const char *Fmt, ...);
-
-// Print using raw syscalls, useful when printing at early init stages.
-void RawPrint(const char *Str);
-
-// Platform specific functions:
-bool IsFile(const std::string &Path);
-bool IsDirectory(const std::string &Path);
-size_t FileSize(const std::string &Path);
-
-void ListFilesInDirRecursive(const std::string &Dir, long *Epoch,
- Vector<std::string> *V, bool TopDir);
-
-bool MkDirRecursive(const std::string &Dir);
-void RmDirRecursive(const std::string &Dir);
-
-// Iterate files and dirs inside Dir, recursively.
-// Call DirPreCallback/DirPostCallback on dirs before/after
-// calling FileCallback on files.
-void IterateDirRecursive(const std::string &Dir,
- void (*DirPreCallback)(const std::string &Dir),
- void (*DirPostCallback)(const std::string &Dir),
- void (*FileCallback)(const std::string &Dir));
-
-struct SizedFile {
- std::string File;
- size_t Size;
- bool operator<(const SizedFile &B) const { return Size < B.Size; }
-};
-
-void GetSizedFilesFromDir(const std::string &Dir, Vector<SizedFile> *V);
-
-char GetSeparator();
-bool IsSeparator(char C);
-// Similar to the basename utility: returns the file name w/o the dir prefix.
-std::string Basename(const std::string &Path);
-
-FILE* OpenFile(int Fd, const char *Mode);
-
-int CloseFile(int Fd);
-
-int DuplicateFile(int Fd);
-
-void RemoveFile(const std::string &Path);
-void RenameFile(const std::string &OldPath, const std::string &NewPath);
-
-intptr_t GetHandleFromFd(int fd);
-
-void MkDir(const std::string &Path);
-void RmDir(const std::string &Path);
-
-const std::string &getDevNull();
-
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_IO_H
diff --git a/contrib/libs/libfuzzer12/FuzzerIOPosix.cpp b/contrib/libs/libfuzzer12/FuzzerIOPosix.cpp
deleted file mode 100644
index 4706a40959b..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerIOPosix.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-//===- FuzzerIOPosix.cpp - IO utils for Posix. ----------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// IO functions implementation using Posix API.
-//===----------------------------------------------------------------------===//
-#include "FuzzerPlatform.h"
-#if LIBFUZZER_POSIX || LIBFUZZER_FUCHSIA
-
-#include "FuzzerExtFunctions.h"
-#include "FuzzerIO.h"
-#include <cstdarg>
-#include <cstdio>
-#include <dirent.h>
-#include <fstream>
-#include <iterator>
-#include <libgen.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-namespace fuzzer {
-
-bool IsFile(const std::string &Path) {
- struct stat St;
- if (stat(Path.c_str(), &St))
- return false;
- return S_ISREG(St.st_mode);
-}
-
-bool IsDirectory(const std::string &Path) {
- struct stat St;
- if (stat(Path.c_str(), &St))
- return false;
- return S_ISDIR(St.st_mode);
-}
-
-size_t FileSize(const std::string &Path) {
- struct stat St;
- if (stat(Path.c_str(), &St))
- return 0;
- return St.st_size;
-}
-
-std::string Basename(const std::string &Path) {
- size_t Pos = Path.rfind(GetSeparator());
- if (Pos == std::string::npos) return Path;
- assert(Pos < Path.size());
- return Path.substr(Pos + 1);
-}
-
-void ListFilesInDirRecursive(const std::string &Dir, long *Epoch,
- Vector<std::string> *V, bool TopDir) {
- auto E = GetEpoch(Dir);
- if (Epoch)
- if (E && *Epoch >= E) return;
-
- DIR *D = opendir(Dir.c_str());
- if (!D) {
- Printf("%s: %s; exiting\n", strerror(errno), Dir.c_str());
- exit(1);
- }
- while (auto E = readdir(D)) {
- std::string Path = DirPlusFile(Dir, E->d_name);
- if (E->d_type == DT_REG || E->d_type == DT_LNK ||
- (E->d_type == DT_UNKNOWN && IsFile(Path)))
- V->push_back(Path);
- else if ((E->d_type == DT_DIR ||
- (E->d_type == DT_UNKNOWN && IsDirectory(Path))) &&
- *E->d_name != '.')
- ListFilesInDirRecursive(Path, Epoch, V, false);
- }
- closedir(D);
- if (Epoch && TopDir)
- *Epoch = E;
-}
-
-
-void IterateDirRecursive(const std::string &Dir,
- void (*DirPreCallback)(const std::string &Dir),
- void (*DirPostCallback)(const std::string &Dir),
- void (*FileCallback)(const std::string &Dir)) {
- DirPreCallback(Dir);
- DIR *D = opendir(Dir.c_str());
- if (!D) return;
- while (auto E = readdir(D)) {
- std::string Path = DirPlusFile(Dir, E->d_name);
- if (E->d_type == DT_REG || E->d_type == DT_LNK ||
- (E->d_type == DT_UNKNOWN && IsFile(Path)))
- FileCallback(Path);
- else if ((E->d_type == DT_DIR ||
- (E->d_type == DT_UNKNOWN && IsDirectory(Path))) &&
- *E->d_name != '.')
- IterateDirRecursive(Path, DirPreCallback, DirPostCallback, FileCallback);
- }
- closedir(D);
- DirPostCallback(Dir);
-}
-
-char GetSeparator() {
- return '/';
-}
-
-bool IsSeparator(char C) {
- return C == '/';
-}
-
-FILE* OpenFile(int Fd, const char* Mode) {
- return fdopen(Fd, Mode);
-}
-
-int CloseFile(int fd) {
- return close(fd);
-}
-
-int DuplicateFile(int Fd) {
- return dup(Fd);
-}
-
-void RemoveFile(const std::string &Path) {
- unlink(Path.c_str());
-}
-
-void RenameFile(const std::string &OldPath, const std::string &NewPath) {
- rename(OldPath.c_str(), NewPath.c_str());
-}
-
-intptr_t GetHandleFromFd(int fd) {
- return static_cast<intptr_t>(fd);
-}
-
-std::string DirName(const std::string &FileName) {
- char *Tmp = new char[FileName.size() + 1];
- memcpy(Tmp, FileName.c_str(), FileName.size() + 1);
- std::string Res = dirname(Tmp);
- delete [] Tmp;
- return Res;
-}
-
-std::string TmpDir() {
- if (auto Env = getenv("TMPDIR"))
- return Env;
- return "/tmp";
-}
-
-bool IsInterestingCoverageFile(const std::string &FileName) {
- if (FileName.find("compiler-rt/lib/") != std::string::npos)
- return false; // sanitizer internal.
- if (FileName.find("/usr/lib/") != std::string::npos)
- return false;
- if (FileName.find("/usr/include/") != std::string::npos)
- return false;
- if (FileName == "<null>")
- return false;
- return true;
-}
-
-void RawPrint(const char *Str) {
- (void)write(2, Str, strlen(Str));
-}
-
-void MkDir(const std::string &Path) {
- mkdir(Path.c_str(), 0700);
-}
-
-void RmDir(const std::string &Path) {
- rmdir(Path.c_str());
-}
-
-const std::string &getDevNull() {
- static const std::string devNull = "/dev/null";
- return devNull;
-}
-
-} // namespace fuzzer
-
-#endif // LIBFUZZER_POSIX
diff --git a/contrib/libs/libfuzzer12/FuzzerIOWindows.cpp b/contrib/libs/libfuzzer12/FuzzerIOWindows.cpp
deleted file mode 100644
index 61ad35e281f..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerIOWindows.cpp
+++ /dev/null
@@ -1,425 +0,0 @@
-//===- FuzzerIOWindows.cpp - IO utils for Windows. ------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// IO functions implementation for Windows.
-//===----------------------------------------------------------------------===//
-#include "FuzzerPlatform.h"
-#if LIBFUZZER_WINDOWS
-
-#include "FuzzerExtFunctions.h"
-#include "FuzzerIO.h"
-#include <cstdarg>
-#include <cstdio>
-#include <fstream>
-#include <io.h>
-#include <iterator>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <windows.h>
-
-namespace fuzzer {
-
-static bool IsFile(const std::string &Path, const DWORD &FileAttributes) {
-
- if (FileAttributes & FILE_ATTRIBUTE_NORMAL)
- return true;
-
- if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- return false;
-
- HANDLE FileHandle(
- CreateFileA(Path.c_str(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS, 0));
-
- if (FileHandle == INVALID_HANDLE_VALUE) {
- Printf("CreateFileA() failed for \"%s\" (Error code: %lu).\n", Path.c_str(),
- GetLastError());
- return false;
- }
-
- DWORD FileType = GetFileType(FileHandle);
-
- if (FileType == FILE_TYPE_UNKNOWN) {
- Printf("GetFileType() failed for \"%s\" (Error code: %lu).\n", Path.c_str(),
- GetLastError());
- CloseHandle(FileHandle);
- return false;
- }
-
- if (FileType != FILE_TYPE_DISK) {
- CloseHandle(FileHandle);
- return false;
- }
-
- CloseHandle(FileHandle);
- return true;
-}
-
-bool IsFile(const std::string &Path) {
- DWORD Att = GetFileAttributesA(Path.c_str());
-
- if (Att == INVALID_FILE_ATTRIBUTES) {
- Printf("GetFileAttributesA() failed for \"%s\" (Error code: %lu).\n",
- Path.c_str(), GetLastError());
- return false;
- }
-
- return IsFile(Path, Att);
-}
-
-static bool IsDir(DWORD FileAttrs) {
- if (FileAttrs == INVALID_FILE_ATTRIBUTES) return false;
- return FileAttrs & FILE_ATTRIBUTE_DIRECTORY;
-}
-
-bool IsDirectory(const std::string &Path) {
- DWORD Att = GetFileAttributesA(Path.c_str());
-
- if (Att == INVALID_FILE_ATTRIBUTES) {
- Printf("GetFileAttributesA() failed for \"%s\" (Error code: %lu).\n",
- Path.c_str(), GetLastError());
- return false;
- }
-
- return IsDir(Att);
-}
-
-std::string Basename(const std::string &Path) {
- size_t Pos = Path.find_last_of("/\\");
- if (Pos == std::string::npos) return Path;
- assert(Pos < Path.size());
- return Path.substr(Pos + 1);
-}
-
-size_t FileSize(const std::string &Path) {
- WIN32_FILE_ATTRIBUTE_DATA attr;
- if (!GetFileAttributesExA(Path.c_str(), GetFileExInfoStandard, &attr)) {
- DWORD LastError = GetLastError();
- if (LastError != ERROR_FILE_NOT_FOUND)
- Printf("GetFileAttributesExA() failed for \"%s\" (Error code: %lu).\n",
- Path.c_str(), LastError);
- return 0;
- }
- ULARGE_INTEGER size;
- size.HighPart = attr.nFileSizeHigh;
- size.LowPart = attr.nFileSizeLow;
- return size.QuadPart;
-}
-
-void ListFilesInDirRecursive(const std::string &Dir, long *Epoch,
- Vector<std::string> *V, bool TopDir) {
- auto E = GetEpoch(Dir);
- if (Epoch)
- if (E && *Epoch >= E) return;
-
- std::string Path(Dir);
- assert(!Path.empty());
- if (Path.back() != '\\')
- Path.push_back('\\');
- Path.push_back('*');
-
- // Get the first directory entry.
- WIN32_FIND_DATAA FindInfo;
- HANDLE FindHandle(FindFirstFileA(Path.c_str(), &FindInfo));
- if (FindHandle == INVALID_HANDLE_VALUE)
- {
- if (GetLastError() == ERROR_FILE_NOT_FOUND)
- return;
- Printf("No such file or directory: %s; exiting\n", Dir.c_str());
- exit(1);
- }
-
- do {
- std::string FileName = DirPlusFile(Dir, FindInfo.cFileName);
-
- if (FindInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- size_t FilenameLen = strlen(FindInfo.cFileName);
- if ((FilenameLen == 1 && FindInfo.cFileName[0] == '.') ||
- (FilenameLen == 2 && FindInfo.cFileName[0] == '.' &&
- FindInfo.cFileName[1] == '.'))
- continue;
-
- ListFilesInDirRecursive(FileName, Epoch, V, false);
- }
- else if (IsFile(FileName, FindInfo.dwFileAttributes))
- V->push_back(FileName);
- } while (FindNextFileA(FindHandle, &FindInfo));
-
- DWORD LastError = GetLastError();
- if (LastError != ERROR_NO_MORE_FILES)
- Printf("FindNextFileA failed (Error code: %lu).\n", LastError);
-
- FindClose(FindHandle);
-
- if (Epoch && TopDir)
- *Epoch = E;
-}
-
-
-void IterateDirRecursive(const std::string &Dir,
- void (*DirPreCallback)(const std::string &Dir),
- void (*DirPostCallback)(const std::string &Dir),
- void (*FileCallback)(const std::string &Dir)) {
- // TODO(metzman): Implement ListFilesInDirRecursive via this function.
- DirPreCallback(Dir);
-
- DWORD DirAttrs = GetFileAttributesA(Dir.c_str());
- if (!IsDir(DirAttrs)) return;
-
- std::string TargetDir(Dir);
- assert(!TargetDir.empty());
- if (TargetDir.back() != '\\') TargetDir.push_back('\\');
- TargetDir.push_back('*');
-
- WIN32_FIND_DATAA FindInfo;
- // Find the directory's first file.
- HANDLE FindHandle = FindFirstFileA(TargetDir.c_str(), &FindInfo);
- if (FindHandle == INVALID_HANDLE_VALUE) {
- DWORD LastError = GetLastError();
- if (LastError != ERROR_FILE_NOT_FOUND) {
- // If the directory isn't empty, then something abnormal is going on.
- Printf("FindFirstFileA failed for %s (Error code: %lu).\n", Dir.c_str(),
- LastError);
- }
- return;
- }
-
- do {
- std::string Path = DirPlusFile(Dir, FindInfo.cFileName);
- DWORD PathAttrs = FindInfo.dwFileAttributes;
- if (IsDir(PathAttrs)) {
- // Is Path the current directory (".") or the parent ("..")?
- if (strcmp(FindInfo.cFileName, ".") == 0 ||
- strcmp(FindInfo.cFileName, "..") == 0)
- continue;
- IterateDirRecursive(Path, DirPreCallback, DirPostCallback, FileCallback);
- } else if (PathAttrs != INVALID_FILE_ATTRIBUTES) {
- FileCallback(Path);
- }
- } while (FindNextFileA(FindHandle, &FindInfo));
-
- DWORD LastError = GetLastError();
- if (LastError != ERROR_NO_MORE_FILES)
- Printf("FindNextFileA failed for %s (Error code: %lu).\n", Dir.c_str(),
- LastError);
-
- FindClose(FindHandle);
- DirPostCallback(Dir);
-}
-
-char GetSeparator() {
- return '\\';
-}
-
-FILE* OpenFile(int Fd, const char* Mode) {
- return _fdopen(Fd, Mode);
-}
-
-int CloseFile(int Fd) {
- return _close(Fd);
-}
-
-int DuplicateFile(int Fd) {
- return _dup(Fd);
-}
-
-void RemoveFile(const std::string &Path) {
- _unlink(Path.c_str());
-}
-
-void RenameFile(const std::string &OldPath, const std::string &NewPath) {
- rename(OldPath.c_str(), NewPath.c_str());
-}
-
-intptr_t GetHandleFromFd(int fd) {
- return _get_osfhandle(fd);
-}
-
-bool IsSeparator(char C) {
- return C == '\\' || C == '/';
-}
-
-// Parse disk designators, like "C:\". If Relative == true, also accepts: "C:".
-// Returns number of characters considered if successful.
-static size_t ParseDrive(const std::string &FileName, const size_t Offset,
- bool Relative = true) {
- if (Offset + 1 >= FileName.size() || FileName[Offset + 1] != ':')
- return 0;
- if (Offset + 2 >= FileName.size() || !IsSeparator(FileName[Offset + 2])) {
- if (!Relative) // Accept relative path?
- return 0;
- else
- return 2;
- }
- return 3;
-}
-
-// Parse a file name, like: SomeFile.txt
-// Returns number of characters considered if successful.
-static size_t ParseFileName(const std::string &FileName, const size_t Offset) {
- size_t Pos = Offset;
- const size_t End = FileName.size();
- for(; Pos < End && !IsSeparator(FileName[Pos]); ++Pos)
- ;
- return Pos - Offset;
-}
-
-// Parse a directory ending in separator, like: `SomeDir\`
-// Returns number of characters considered if successful.
-static size_t ParseDir(const std::string &FileName, const size_t Offset) {
- size_t Pos = Offset;
- const size_t End = FileName.size();
- if (Pos >= End || IsSeparator(FileName[Pos]))
- return 0;
- for(; Pos < End && !IsSeparator(FileName[Pos]); ++Pos)
- ;
- if (Pos >= End)
- return 0;
- ++Pos; // Include separator.
- return Pos - Offset;
-}
-
-// Parse a servername and share, like: `SomeServer\SomeShare\`
-// Returns number of characters considered if successful.
-static size_t ParseServerAndShare(const std::string &FileName,
- const size_t Offset) {
- size_t Pos = Offset, Res;
- if (!(Res = ParseDir(FileName, Pos)))
- return 0;
- Pos += Res;
- if (!(Res = ParseDir(FileName, Pos)))
- return 0;
- Pos += Res;
- return Pos - Offset;
-}
-
-// Parse the given Ref string from the position Offset, to exactly match the given
-// string Patt.
-// Returns number of characters considered if successful.
-static size_t ParseCustomString(const std::string &Ref, size_t Offset,
- const char *Patt) {
- size_t Len = strlen(Patt);
- if (Offset + Len > Ref.size())
- return 0;
- return Ref.compare(Offset, Len, Patt) == 0 ? Len : 0;
-}
-
-// Parse a location, like:
-// \\?\UNC\Server\Share\ \\?\C:\ \\Server\Share\ \ C:\ C:
-// Returns number of characters considered if successful.
-static size_t ParseLocation(const std::string &FileName) {
- size_t Pos = 0, Res;
-
- if ((Res = ParseCustomString(FileName, Pos, R"(\\?\)"))) {
- Pos += Res;
- if ((Res = ParseCustomString(FileName, Pos, R"(UNC\)"))) {
- Pos += Res;
- if ((Res = ParseServerAndShare(FileName, Pos)))
- return Pos + Res;
- return 0;
- }
- if ((Res = ParseDrive(FileName, Pos, false)))
- return Pos + Res;
- return 0;
- }
-
- if (Pos < FileName.size() && IsSeparator(FileName[Pos])) {
- ++Pos;
- if (Pos < FileName.size() && IsSeparator(FileName[Pos])) {
- ++Pos;
- if ((Res = ParseServerAndShare(FileName, Pos)))
- return Pos + Res;
- return 0;
- }
- return Pos;
- }
-
- if ((Res = ParseDrive(FileName, Pos)))
- return Pos + Res;
-
- return Pos;
-}
-
-std::string DirName(const std::string &FileName) {
- size_t LocationLen = ParseLocation(FileName);
- size_t DirLen = 0, Res;
- while ((Res = ParseDir(FileName, LocationLen + DirLen)))
- DirLen += Res;
- size_t FileLen = ParseFileName(FileName, LocationLen + DirLen);
-
- if (LocationLen + DirLen + FileLen != FileName.size()) {
- Printf("DirName() failed for \"%s\", invalid path.\n", FileName.c_str());
- exit(1);
- }
-
- if (DirLen) {
- --DirLen; // Remove trailing separator.
- if (!FileLen) { // Path ended in separator.
- assert(DirLen);
- // Remove file name from Dir.
- while (DirLen && !IsSeparator(FileName[LocationLen + DirLen - 1]))
- --DirLen;
- if (DirLen) // Remove trailing separator.
- --DirLen;
- }
- }
-
- if (!LocationLen) { // Relative path.
- if (!DirLen)
- return ".";
- return std::string(".\\").append(FileName, 0, DirLen);
- }
-
- return FileName.substr(0, LocationLen + DirLen);
-}
-
-std::string TmpDir() {
- std::string Tmp;
- Tmp.resize(MAX_PATH + 1);
- DWORD Size = GetTempPathA(Tmp.size(), &Tmp[0]);
- if (Size == 0) {
- Printf("Couldn't get Tmp path.\n");
- exit(1);
- }
- Tmp.resize(Size);
- return Tmp;
-}
-
-bool IsInterestingCoverageFile(const std::string &FileName) {
- if (FileName.find("Program Files") != std::string::npos)
- return false;
- if (FileName.find("compiler-rt\\lib\\") != std::string::npos)
- return false; // sanitizer internal.
- if (FileName == "<null>")
- return false;
- return true;
-}
-
-void RawPrint(const char *Str) {
- _write(2, Str, strlen(Str));
-}
-
-void MkDir(const std::string &Path) {
- if (CreateDirectoryA(Path.c_str(), nullptr)) return;
- Printf("CreateDirectoryA failed for %s (Error code: %lu).\n", Path.c_str(),
- GetLastError());
-}
-
-void RmDir(const std::string &Path) {
- if (RemoveDirectoryA(Path.c_str())) return;
- Printf("RemoveDirectoryA failed for %s (Error code: %lu).\n", Path.c_str(),
- GetLastError());
-}
-
-const std::string &getDevNull() {
- static const std::string devNull = "NUL";
- return devNull;
-}
-
-} // namespace fuzzer
-
-#endif // LIBFUZZER_WINDOWS
diff --git a/contrib/libs/libfuzzer12/FuzzerInterface.h b/contrib/libs/libfuzzer12/FuzzerInterface.h
deleted file mode 100644
index f1130dc3968..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerInterface.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//===- FuzzerInterface.h - Interface header for the Fuzzer ------*- 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
-//
-//===----------------------------------------------------------------------===//
-// Define the interface between libFuzzer and the library being tested.
-//===----------------------------------------------------------------------===//
-
-// NOTE: the libFuzzer interface is thin and in the majority of cases
-// you should not include this file into your target. In 95% of cases
-// all you need is to define the following function in your file:
-// extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
-
-// WARNING: keep the interface in C.
-
-#ifndef LLVM_FUZZER_INTERFACE_H
-#define LLVM_FUZZER_INTERFACE_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-// Define FUZZER_INTERFACE_VISIBILITY to set default visibility in a way that
-// doesn't break MSVC.
-#if defined(_WIN32)
-#define FUZZER_INTERFACE_VISIBILITY __declspec(dllexport)
-#else
-#define FUZZER_INTERFACE_VISIBILITY __attribute__((visibility("default")))
-#endif
-
-// Mandatory user-provided target function.
-// Executes the code under test with [Data, Data+Size) as the input.
-// libFuzzer will invoke this function *many* times with different inputs.
-// Must return 0.
-FUZZER_INTERFACE_VISIBILITY int
-LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
-
-// Optional user-provided initialization function.
-// If provided, this function will be called by libFuzzer once at startup.
-// It may read and modify argc/argv.
-// Must return 0.
-FUZZER_INTERFACE_VISIBILITY int LLVMFuzzerInitialize(int *argc, char ***argv);
-FUZZER_INTERFACE_VISIBILITY void LLVMFuzzerCleanup();
-
-// Optional user-provided custom mutator.
-// Mutates raw data in [Data, Data+Size) inplace.
-// Returns the new size, which is not greater than MaxSize.
-// Given the same Seed produces the same mutation.
-FUZZER_INTERFACE_VISIBILITY size_t
-LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, size_t MaxSize,
- unsigned int Seed);
-
-// Optional user-provided custom cross-over function.
-// Combines pieces of Data1 & Data2 together into Out.
-// Returns the new size, which is not greater than MaxOutSize.
-// Should produce the same mutation given the same Seed.
-FUZZER_INTERFACE_VISIBILITY size_t
-LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1,
- const uint8_t *Data2, size_t Size2, uint8_t *Out,
- size_t MaxOutSize, unsigned int Seed);
-
-// Experimental, may go away in future.
-// libFuzzer-provided function to be used inside LLVMFuzzerCustomMutator.
-// Mutates raw data in [Data, Data+Size) inplace.
-// Returns the new size, which is not greater than MaxSize.
-FUZZER_INTERFACE_VISIBILITY size_t
-LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
-
-#undef FUZZER_INTERFACE_VISIBILITY
-
-#ifdef __cplusplus
-} // extern "C"
-#endif // __cplusplus
-
-#endif // LLVM_FUZZER_INTERFACE_H
diff --git a/contrib/libs/libfuzzer12/FuzzerInternal.h b/contrib/libs/libfuzzer12/FuzzerInternal.h
deleted file mode 100644
index 37c8a01dc3c..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerInternal.h
+++ /dev/null
@@ -1,174 +0,0 @@
-//===- FuzzerInternal.h - Internal header for the Fuzzer --------*- 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
-//
-//===----------------------------------------------------------------------===//
-// Define the main class fuzzer::Fuzzer and most functions.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_INTERNAL_H
-#define LLVM_FUZZER_INTERNAL_H
-
-#include "FuzzerDataFlowTrace.h"
-#include "FuzzerDefs.h"
-#include "FuzzerExtFunctions.h"
-#include "FuzzerInterface.h"
-#include "FuzzerOptions.h"
-#include "FuzzerSHA1.h"
-#include "FuzzerValueBitMap.h"
-#include <algorithm>
-#include <atomic>
-#include <chrono>
-#include <climits>
-#include <cstdlib>
-#include <string.h>
-
-namespace fuzzer {
-
-using namespace std::chrono;
-
-class Fuzzer {
-public:
-
- Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
- FuzzingOptions Options);
- ~Fuzzer();
- void Loop(Vector<SizedFile> &CorporaFiles);
- void ReadAndExecuteSeedCorpora(Vector<SizedFile> &CorporaFiles);
- void MinimizeCrashLoop(const Unit &U);
- void RereadOutputCorpus(size_t MaxSize);
-
- size_t secondsSinceProcessStartUp() {
- return duration_cast<seconds>(system_clock::now() - ProcessStartTime)
- .count();
- }
-
- bool TimedOut() {
- return Options.MaxTotalTimeSec > 0 &&
- secondsSinceProcessStartUp() >
- static_cast<size_t>(Options.MaxTotalTimeSec);
- }
-
- size_t execPerSec() {
- size_t Seconds = secondsSinceProcessStartUp();
- return Seconds ? TotalNumberOfRuns / Seconds : 0;
- }
-
- size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
-
- static void StaticAlarmCallback();
- static void StaticCrashSignalCallback();
- static void StaticExitCallback();
- static void StaticInterruptCallback();
- static void StaticFileSizeExceedCallback();
- static void StaticGracefulExitCallback();
-
- void ExecuteCallback(const uint8_t *Data, size_t Size);
- bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false,
- InputInfo *II = nullptr, bool ForceAddToCorpus = false,
- bool *FoundUniqFeatures = nullptr);
- void TPCUpdateObservedPCs();
-
- // Merge Corpora[1:] into Corpora[0].
- void Merge(const Vector<std::string> &Corpora);
- void CrashResistantMergeInternalStep(const std::string &ControlFilePath);
- MutationDispatcher &GetMD() { return MD; }
- void PrintFinalStats();
- void SetMaxInputLen(size_t MaxInputLen);
- void SetMaxMutationLen(size_t MaxMutationLen);
- void RssLimitCallback();
-
- bool InFuzzingThread() const { return IsMyThread; }
- size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const;
- void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
- bool DuringInitialCorpusExecution);
-
- void HandleMalloc(size_t Size);
- static void MaybeExitGracefully();
- std::string WriteToOutputCorpus(const Unit &U);
-
-private:
- void AlarmCallback();
- void CrashCallback();
- void ExitCallback();
- void CrashOnOverwrittenData();
- void InterruptCallback();
- void MutateAndTestOne();
- void PurgeAllocator();
- void ReportNewCoverage(InputInfo *II, const Unit &U);
- void PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size);
- void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
- void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0,
- size_t Features = 0);
- void PrintStatusForNewUnit(const Unit &U, const char *Text);
- void CheckExitOnSrcPosOrItem();
-
- static void StaticDeathCallback();
- void DumpCurrentUnit(const char *Prefix);
- void DeathCallback();
-
- void AllocateCurrentUnitData();
- uint8_t *CurrentUnitData = nullptr;
- std::atomic<size_t> CurrentUnitSize;
- uint8_t BaseSha1[kSHA1NumBytes]; // Checksum of the base unit.
-
- bool GracefulExitRequested = false;
-
- size_t TotalNumberOfRuns = 0;
- size_t NumberOfNewUnitsAdded = 0;
-
- size_t LastCorpusUpdateRun = 0;
-
- bool HasMoreMallocsThanFrees = false;
- size_t NumberOfLeakDetectionAttempts = 0;
-
- system_clock::time_point LastAllocatorPurgeAttemptTime = system_clock::now();
-
- UserCallback CB;
- InputCorpus &Corpus;
- MutationDispatcher &MD;
- FuzzingOptions Options;
- DataFlowTrace DFT;
-
- system_clock::time_point ProcessStartTime = system_clock::now();
- system_clock::time_point UnitStartTime, UnitStopTime;
- long TimeOfLongestUnitInSeconds = 0;
- long EpochOfLastReadOfOutputCorpus = 0;
-
- size_t MaxInputLen = 0;
- size_t MaxMutationLen = 0;
- size_t TmpMaxMutationLen = 0;
-
- Vector<uint32_t> UniqFeatureSetTmp;
-
- // Need to know our own thread.
- static thread_local bool IsMyThread;
-};
-
-struct ScopedEnableMsanInterceptorChecks {
- ScopedEnableMsanInterceptorChecks() {
- if (EF->__msan_scoped_enable_interceptor_checks)
- EF->__msan_scoped_enable_interceptor_checks();
- }
- ~ScopedEnableMsanInterceptorChecks() {
- if (EF->__msan_scoped_disable_interceptor_checks)
- EF->__msan_scoped_disable_interceptor_checks();
- }
-};
-
-struct ScopedDisableMsanInterceptorChecks {
- ScopedDisableMsanInterceptorChecks() {
- if (EF->__msan_scoped_disable_interceptor_checks)
- EF->__msan_scoped_disable_interceptor_checks();
- }
- ~ScopedDisableMsanInterceptorChecks() {
- if (EF->__msan_scoped_enable_interceptor_checks)
- EF->__msan_scoped_enable_interceptor_checks();
- }
-};
-
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_INTERNAL_H
diff --git a/contrib/libs/libfuzzer12/FuzzerLoop.cpp b/contrib/libs/libfuzzer12/FuzzerLoop.cpp
deleted file mode 100644
index fc53ac086b9..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerLoop.cpp
+++ /dev/null
@@ -1,921 +0,0 @@
-//===- FuzzerLoop.cpp - Fuzzer's main loop --------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Fuzzer's main loop.
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerCorpus.h"
-#include "FuzzerIO.h"
-#include "FuzzerInternal.h"
-#include "FuzzerMutate.h"
-#include "FuzzerPlatform.h"
-#include "FuzzerRandom.h"
-#include "FuzzerTracePC.h"
-#include <algorithm>
-#include <cstring>
-#include <memory>
-#include <mutex>
-#include <set>
-
-#if defined(__has_include)
-#if __has_include(<sanitizer / lsan_interface.h>)
-#include <sanitizer/lsan_interface.h>
-#endif
-#endif
-
-#define NO_SANITIZE_MEMORY
-#if defined(__has_feature)
-#if __has_feature(memory_sanitizer)
-#undef NO_SANITIZE_MEMORY
-#define NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
-#endif
-#endif
-
-namespace fuzzer {
-static const size_t kMaxUnitSizeToPrint = 256;
-
-thread_local bool Fuzzer::IsMyThread;
-
-bool RunningUserCallback = false;
-
-// Only one Fuzzer per process.
-static Fuzzer *F;
-
-// Leak detection is expensive, so we first check if there were more mallocs
-// than frees (using the sanitizer malloc hooks) and only then try to call lsan.
-struct MallocFreeTracer {
- void Start(int TraceLevel) {
- this->TraceLevel = TraceLevel;
- if (TraceLevel)
- Printf("MallocFreeTracer: START\n");
- Mallocs = 0;
- Frees = 0;
- }
- // Returns true if there were more mallocs than frees.
- bool Stop() {
- if (TraceLevel)
- Printf("MallocFreeTracer: STOP %zd %zd (%s)\n", Mallocs.load(),
- Frees.load(), Mallocs == Frees ? "same" : "DIFFERENT");
- bool Result = Mallocs > Frees;
- Mallocs = 0;
- Frees = 0;
- TraceLevel = 0;
- return Result;
- }
- std::atomic<size_t> Mallocs;
- std::atomic<size_t> Frees;
- int TraceLevel = 0;
-
- std::recursive_mutex TraceMutex;
- bool TraceDisabled = false;
-};
-
-static MallocFreeTracer AllocTracer;
-
-// Locks printing and avoids nested hooks triggered from mallocs/frees in
-// sanitizer.
-class TraceLock {
-public:
- TraceLock() : Lock(AllocTracer.TraceMutex) {
- AllocTracer.TraceDisabled = !AllocTracer.TraceDisabled;
- }
- ~TraceLock() { AllocTracer.TraceDisabled = !AllocTracer.TraceDisabled; }
-
- bool IsDisabled() const {
- // This is already inverted value.
- return !AllocTracer.TraceDisabled;
- }
-
-private:
- std::lock_guard<std::recursive_mutex> Lock;
-};
-
-ATTRIBUTE_NO_SANITIZE_MEMORY
-void MallocHook(const volatile void *ptr, size_t size) {
- size_t N = AllocTracer.Mallocs++;
- F->HandleMalloc(size);
- if (int TraceLevel = AllocTracer.TraceLevel) {
- TraceLock Lock;
- if (Lock.IsDisabled())
- return;
- Printf("MALLOC[%zd] %p %zd\n", N, ptr, size);
- if (TraceLevel >= 2 && EF)
- PrintStackTrace();
- }
-}
-
-ATTRIBUTE_NO_SANITIZE_MEMORY
-void FreeHook(const volatile void *ptr) {
- size_t N = AllocTracer.Frees++;
- if (int TraceLevel = AllocTracer.TraceLevel) {
- TraceLock Lock;
- if (Lock.IsDisabled())
- return;
- Printf("FREE[%zd] %p\n", N, ptr);
- if (TraceLevel >= 2 && EF)
- PrintStackTrace();
- }
-}
-
-// Crash on a single malloc that exceeds the rss limit.
-void Fuzzer::HandleMalloc(size_t Size) {
- if (!Options.MallocLimitMb || (Size >> 20) < (size_t)Options.MallocLimitMb)
- return;
- Printf("==%d== ERROR: libFuzzer: out-of-memory (malloc(%zd))\n", GetPid(),
- Size);
- Printf(" To change the out-of-memory limit use -rss_limit_mb=<N>\n\n");
- PrintStackTrace();
- DumpCurrentUnit("oom-");
- Printf("SUMMARY: libFuzzer: out-of-memory\n");
- PrintFinalStats();
- _Exit(Options.OOMExitCode); // Stop right now.
-}
-
-Fuzzer::Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
- FuzzingOptions Options)
- : CB(CB), Corpus(Corpus), MD(MD), Options(Options) {
- if (EF->__sanitizer_set_death_callback)
- EF->__sanitizer_set_death_callback(StaticDeathCallback);
- assert(!F);
- F = this;
- TPC.ResetMaps();
- IsMyThread = true;
- if (Options.DetectLeaks && EF->__sanitizer_install_malloc_and_free_hooks)
- EF->__sanitizer_install_malloc_and_free_hooks(MallocHook, FreeHook);
- TPC.SetUseCounters(Options.UseCounters);
- TPC.SetUseValueProfileMask(Options.UseValueProfile);
-
- if (Options.Verbosity)
- TPC.PrintModuleInfo();
- if (!Options.OutputCorpus.empty() && Options.ReloadIntervalSec)
- EpochOfLastReadOfOutputCorpus = GetEpoch(Options.OutputCorpus);
- MaxInputLen = MaxMutationLen = Options.MaxLen;
- TmpMaxMutationLen = 0; // Will be set once we load the corpus.
- AllocateCurrentUnitData();
- CurrentUnitSize = 0;
- memset(BaseSha1, 0, sizeof(BaseSha1));
-}
-
-Fuzzer::~Fuzzer() {}
-
-void Fuzzer::AllocateCurrentUnitData() {
- if (CurrentUnitData || MaxInputLen == 0)
- return;
- CurrentUnitData = new uint8_t[MaxInputLen];
-}
-
-void Fuzzer::StaticDeathCallback() {
- assert(F);
- F->DeathCallback();
-}
-
-void Fuzzer::DumpCurrentUnit(const char *Prefix) {
- if (!CurrentUnitData)
- return; // Happens when running individual inputs.
- ScopedDisableMsanInterceptorChecks S;
- MD.PrintMutationSequence();
- Printf("; base unit: %s\n", Sha1ToString(BaseSha1).c_str());
- size_t UnitSize = CurrentUnitSize;
- if (UnitSize <= kMaxUnitSizeToPrint) {
- PrintHexArray(CurrentUnitData, UnitSize, "\n");
- PrintASCII(CurrentUnitData, UnitSize, "\n");
- }
- WriteUnitToFileWithPrefix({CurrentUnitData, CurrentUnitData + UnitSize},
- Prefix);
-}
-
-NO_SANITIZE_MEMORY
-void Fuzzer::DeathCallback() {
- DumpCurrentUnit("crash-");
- PrintFinalStats();
-}
-
-void Fuzzer::StaticAlarmCallback() {
- assert(F);
- F->AlarmCallback();
-}
-
-void Fuzzer::StaticCrashSignalCallback() {
- assert(F);
- F->CrashCallback();
-}
-
-void Fuzzer::StaticExitCallback() {
- assert(F);
- F->ExitCallback();
-}
-
-void Fuzzer::StaticInterruptCallback() {
- assert(F);
- F->InterruptCallback();
-}
-
-void Fuzzer::StaticGracefulExitCallback() {
- assert(F);
- F->GracefulExitRequested = true;
- Printf("INFO: signal received, trying to exit gracefully\n");
-}
-
-void Fuzzer::StaticFileSizeExceedCallback() {
- Printf("==%lu== ERROR: libFuzzer: file size exceeded\n", GetPid());
- exit(1);
-}
-
-void Fuzzer::CrashCallback() {
- if (EF->__sanitizer_acquire_crash_state &&
- !EF->__sanitizer_acquire_crash_state())
- return;
- Printf("==%lu== ERROR: libFuzzer: deadly signal\n", GetPid());
- PrintStackTrace();
- Printf("NOTE: libFuzzer has rudimentary signal handlers.\n"
- " Combine libFuzzer with AddressSanitizer or similar for better "
- "crash reports.\n");
- Printf("SUMMARY: libFuzzer: deadly signal\n");
- DumpCurrentUnit("crash-");
- PrintFinalStats();
- _Exit(Options.ErrorExitCode); // Stop right now.
-}
-
-void Fuzzer::ExitCallback() {
- if (!RunningUserCallback)
- return; // This exit did not come from the user callback
- if (EF->__sanitizer_acquire_crash_state &&
- !EF->__sanitizer_acquire_crash_state())
- return;
- Printf("==%lu== ERROR: libFuzzer: fuzz target exited\n", GetPid());
- PrintStackTrace();
- Printf("SUMMARY: libFuzzer: fuzz target exited\n");
- DumpCurrentUnit("crash-");
- PrintFinalStats();
- _Exit(Options.ErrorExitCode);
-}
-
-void Fuzzer::MaybeExitGracefully() {
- if (!F->GracefulExitRequested) return;
- Printf("==%lu== INFO: libFuzzer: exiting as requested\n", GetPid());
- RmDirRecursive(TempPath("FuzzWithFork", ".dir"));
- F->PrintFinalStats();
- _Exit(0);
-}
-
-void Fuzzer::InterruptCallback() {
- if (Options.DumpInterrupted)
- DumpCurrentUnit("interrupted-");
- Printf("==%lu== libFuzzer: run interrupted; exiting\n", GetPid());
- PrintFinalStats();
- ScopedDisableMsanInterceptorChecks S; // RmDirRecursive may call opendir().
- RmDirRecursive(TempPath("FuzzWithFork", ".dir"));
- // Stop right now, don't perform any at-exit actions.
- _Exit(Options.InterruptExitCode);
-}
-
-NO_SANITIZE_MEMORY
-void Fuzzer::AlarmCallback() {
- assert(Options.UnitTimeoutSec > 0);
- // In Windows and Fuchsia, Alarm callback is executed by a different thread.
- // NetBSD's current behavior needs this change too.
-#if !LIBFUZZER_WINDOWS && !LIBFUZZER_NETBSD && !LIBFUZZER_FUCHSIA
- if (!InFuzzingThread())
- return;
-#endif
- if (!RunningUserCallback)
- return; // We have not started running units yet.
- size_t Seconds =
- duration_cast<seconds>(system_clock::now() - UnitStartTime).count();
- if (Seconds == 0)
- return;
- if (Options.Verbosity >= 2)
- Printf("AlarmCallback %zd\n", Seconds);
- if (Seconds >= (size_t)Options.UnitTimeoutSec) {
- if (EF->__sanitizer_acquire_crash_state &&
- !EF->__sanitizer_acquire_crash_state())
- return;
- Printf("ALARM: working on the last Unit for %zd seconds\n", Seconds);
- Printf(" and the timeout value is %d (use -timeout=N to change)\n",
- Options.UnitTimeoutSec);
- DumpCurrentUnit("timeout-");
- Printf("==%lu== ERROR: libFuzzer: timeout after %d seconds\n", GetPid(),
- Seconds);
- PrintStackTrace();
- Printf("SUMMARY: libFuzzer: timeout\n");
- PrintFinalStats();
- _Exit(Options.TimeoutExitCode); // Stop right now.
- }
-}
-
-void Fuzzer::RssLimitCallback() {
- if (EF->__sanitizer_acquire_crash_state &&
- !EF->__sanitizer_acquire_crash_state())
- return;
- Printf(
- "==%lu== ERROR: libFuzzer: out-of-memory (used: %zdMb; limit: %zdMb)\n",
- GetPid(), GetPeakRSSMb(), Options.RssLimitMb);
- Printf(" To change the out-of-memory limit use -rss_limit_mb=<N>\n\n");
- PrintMemoryProfile();
- DumpCurrentUnit("oom-");
- Printf("SUMMARY: libFuzzer: out-of-memory\n");
- PrintFinalStats();
- _Exit(Options.OOMExitCode); // Stop right now.
-}
-
-void Fuzzer::PrintStats(const char *Where, const char *End, size_t Units,
- size_t Features) {
- size_t ExecPerSec = execPerSec();
- if (!Options.Verbosity)
- return;
- Printf("#%zd\t%s", TotalNumberOfRuns, Where);
- if (size_t N = TPC.GetTotalPCCoverage())
- Printf(" cov: %zd", N);
- if (size_t N = Features ? Features : Corpus.NumFeatures())
- Printf(" ft: %zd", N);
- if (!Corpus.empty()) {
- Printf(" corp: %zd", Corpus.NumActiveUnits());
- if (size_t N = Corpus.SizeInBytes()) {
- if (N < (1 << 14))
- Printf("/%zdb", N);
- else if (N < (1 << 24))
- Printf("/%zdKb", N >> 10);
- else
- Printf("/%zdMb", N >> 20);
- }
- if (size_t FF = Corpus.NumInputsThatTouchFocusFunction())
- Printf(" focus: %zd", FF);
- }
- if (TmpMaxMutationLen)
- Printf(" lim: %zd", TmpMaxMutationLen);
- if (Units)
- Printf(" units: %zd", Units);
-
- Printf(" exec/s: %zd", ExecPerSec);
- Printf(" rss: %zdMb", GetPeakRSSMb());
- Printf("%s", End);
-}
-
-void Fuzzer::PrintFinalStats() {
- if (Options.PrintFullCoverage)
- TPC.PrintCoverage(/*PrintAllCounters=*/true);
- if (Options.PrintCoverage)
- TPC.PrintCoverage(/*PrintAllCounters=*/false);
- if (Options.PrintCorpusStats)
- Corpus.PrintStats();
- if (!Options.PrintFinalStats)
- return;
- size_t ExecPerSec = execPerSec();
- Printf("stat::number_of_executed_units: %zd\n", TotalNumberOfRuns);
- Printf("stat::average_exec_per_sec: %zd\n", ExecPerSec);
- Printf("stat::new_units_added: %zd\n", NumberOfNewUnitsAdded);
- Printf("stat::slowest_unit_time_sec: %zd\n", TimeOfLongestUnitInSeconds);
- Printf("stat::peak_rss_mb: %zd\n", GetPeakRSSMb());
-}
-
-void Fuzzer::SetMaxInputLen(size_t MaxInputLen) {
- assert(this->MaxInputLen == 0); // Can only reset MaxInputLen from 0 to non-0.
- assert(MaxInputLen);
- this->MaxInputLen = MaxInputLen;
- this->MaxMutationLen = MaxInputLen;
- AllocateCurrentUnitData();
- Printf("INFO: -max_len is not provided; "
- "libFuzzer will not generate inputs larger than %zd bytes\n",
- MaxInputLen);
-}
-
-void Fuzzer::SetMaxMutationLen(size_t MaxMutationLen) {
- assert(MaxMutationLen && MaxMutationLen <= MaxInputLen);
- this->MaxMutationLen = MaxMutationLen;
-}
-
-void Fuzzer::CheckExitOnSrcPosOrItem() {
- if (!Options.ExitOnSrcPos.empty()) {
- static auto *PCsSet = new Set<uintptr_t>;
- auto HandlePC = [&](const TracePC::PCTableEntry *TE) {
- if (!PCsSet->insert(TE->PC).second)
- return;
- std::string Descr = DescribePC("%F %L", TE->PC + 1);
- if (Descr.find(Options.ExitOnSrcPos) != std::string::npos) {
- Printf("INFO: found line matching '%s', exiting.\n",
- Options.ExitOnSrcPos.c_str());
- _Exit(0);
- }
- };
- TPC.ForEachObservedPC(HandlePC);
- }
- if (!Options.ExitOnItem.empty()) {
- if (Corpus.HasUnit(Options.ExitOnItem)) {
- Printf("INFO: found item with checksum '%s', exiting.\n",
- Options.ExitOnItem.c_str());
- _Exit(0);
- }
- }
-}
-
-void Fuzzer::RereadOutputCorpus(size_t MaxSize) {
- if (Options.OutputCorpus.empty() || !Options.ReloadIntervalSec)
- return;
- Vector<Unit> AdditionalCorpus;
- ReadDirToVectorOfUnits(Options.OutputCorpus.c_str(), &AdditionalCorpus,
- &EpochOfLastReadOfOutputCorpus, MaxSize,
- /*ExitOnError*/ false);
- if (Options.Verbosity >= 2)
- Printf("Reload: read %zd new units.\n", AdditionalCorpus.size());
- bool Reloaded = false;
- for (auto &U : AdditionalCorpus) {
- if (U.size() > MaxSize)
- U.resize(MaxSize);
- if (!Corpus.HasUnit(U)) {
- if (RunOne(U.data(), U.size())) {
- CheckExitOnSrcPosOrItem();
- Reloaded = true;
- }
- }
- }
- if (Reloaded)
- PrintStats("RELOAD");
-}
-
-void Fuzzer::PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size) {
- auto TimeOfUnit =
- duration_cast<seconds>(UnitStopTime - UnitStartTime).count();
- if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1)) &&
- secondsSinceProcessStartUp() >= 2)
- PrintStats("pulse ");
- if (TimeOfUnit > TimeOfLongestUnitInSeconds * 1.1 &&
- TimeOfUnit >= Options.ReportSlowUnits) {
- TimeOfLongestUnitInSeconds = TimeOfUnit;
- Printf("Slowest unit: %zd s:\n", TimeOfLongestUnitInSeconds);
- WriteUnitToFileWithPrefix({Data, Data + Size}, "slow-unit-");
- }
-}
-
-static void WriteFeatureSetToFile(const std::string &FeaturesDir,
- const std::string &FileName,
- const Vector<uint32_t> &FeatureSet) {
- if (FeaturesDir.empty() || FeatureSet.empty()) return;
- WriteToFile(reinterpret_cast<const uint8_t *>(FeatureSet.data()),
- FeatureSet.size() * sizeof(FeatureSet[0]),
- DirPlusFile(FeaturesDir, FileName));
-}
-
-static void RenameFeatureSetFile(const std::string &FeaturesDir,
- const std::string &OldFile,
- const std::string &NewFile) {
- if (FeaturesDir.empty()) return;
- RenameFile(DirPlusFile(FeaturesDir, OldFile),
- DirPlusFile(FeaturesDir, NewFile));
-}
-
-static void WriteEdgeToMutationGraphFile(const std::string &MutationGraphFile,
- const InputInfo *II,
- const InputInfo *BaseII,
- const std::string &MS) {
- if (MutationGraphFile.empty())
- return;
-
- std::string Sha1 = Sha1ToString(II->Sha1);
-
- std::string OutputString;
-
- // Add a new vertex.
- OutputString.append("\"");
- OutputString.append(Sha1);
- OutputString.append("\"\n");
-
- // Add a new edge if there is base input.
- if (BaseII) {
- std::string BaseSha1 = Sha1ToString(BaseII->Sha1);
- OutputString.append("\"");
- OutputString.append(BaseSha1);
- OutputString.append("\" -> \"");
- OutputString.append(Sha1);
- OutputString.append("\" [label=\"");
- OutputString.append(MS);
- OutputString.append("\"];\n");
- }
-
- AppendToFile(OutputString, MutationGraphFile);
-}
-
-bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile,
- InputInfo *II, bool ForceAddToCorpus,
- bool *FoundUniqFeatures) {
- if (!Size)
- return false;
-
- ExecuteCallback(Data, Size);
- auto TimeOfUnit = duration_cast<microseconds>(UnitStopTime - UnitStartTime);
-
- UniqFeatureSetTmp.clear();
- size_t FoundUniqFeaturesOfII = 0;
- size_t NumUpdatesBefore = Corpus.NumFeatureUpdates();
- TPC.CollectFeatures([&](size_t Feature) {
- if (Corpus.AddFeature(Feature, Size, Options.Shrink))
- UniqFeatureSetTmp.push_back(Feature);
- if (Options.Entropic)
- Corpus.UpdateFeatureFrequency(II, Feature);
- if (Options.ReduceInputs && II && !II->NeverReduce)
- if (std::binary_search(II->UniqFeatureSet.begin(),
- II->UniqFeatureSet.end(), Feature))
- FoundUniqFeaturesOfII++;
- });
- if (FoundUniqFeatures)
- *FoundUniqFeatures = FoundUniqFeaturesOfII;
- PrintPulseAndReportSlowInput(Data, Size);
- size_t NumNewFeatures = Corpus.NumFeatureUpdates() - NumUpdatesBefore;
- if (NumNewFeatures || ForceAddToCorpus) {
- TPC.UpdateObservedPCs();
- auto NewII =
- Corpus.AddToCorpus({Data, Data + Size}, NumNewFeatures, MayDeleteFile,
- TPC.ObservedFocusFunction(), ForceAddToCorpus,
- TimeOfUnit, UniqFeatureSetTmp, DFT, II);
- WriteFeatureSetToFile(Options.FeaturesDir, Sha1ToString(NewII->Sha1),
- NewII->UniqFeatureSet);
- WriteEdgeToMutationGraphFile(Options.MutationGraphFile, NewII, II,
- MD.MutationSequence());
- return true;
- }
- if (II && FoundUniqFeaturesOfII &&
- II->DataFlowTraceForFocusFunction.empty() &&
- FoundUniqFeaturesOfII == II->UniqFeatureSet.size() &&
- II->U.size() > Size) {
- auto OldFeaturesFile = Sha1ToString(II->Sha1);
- Corpus.Replace(II, {Data, Data + Size});
- RenameFeatureSetFile(Options.FeaturesDir, OldFeaturesFile,
- Sha1ToString(II->Sha1));
- return true;
- }
- return false;
-}
-
-void Fuzzer::TPCUpdateObservedPCs() { TPC.UpdateObservedPCs(); }
-
-size_t Fuzzer::GetCurrentUnitInFuzzingThead(const uint8_t **Data) const {
- assert(InFuzzingThread());
- *Data = CurrentUnitData;
- return CurrentUnitSize;
-}
-
-void Fuzzer::CrashOnOverwrittenData() {
- Printf("==%d== ERROR: libFuzzer: fuzz target overwrites its const input\n",
- GetPid());
- PrintStackTrace();
- Printf("SUMMARY: libFuzzer: overwrites-const-input\n");
- DumpCurrentUnit("crash-");
- PrintFinalStats();
- _Exit(Options.ErrorExitCode); // Stop right now.
-}
-
-// Compare two arrays, but not all bytes if the arrays are large.
-static bool LooseMemeq(const uint8_t *A, const uint8_t *B, size_t Size) {
- const size_t Limit = 64;
- if (Size <= 64)
- return !memcmp(A, B, Size);
- // Compare first and last Limit/2 bytes.
- return !memcmp(A, B, Limit / 2) &&
- !memcmp(A + Size - Limit / 2, B + Size - Limit / 2, Limit / 2);
-}
-
-void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) {
- TPC.RecordInitialStack();
- TotalNumberOfRuns++;
- assert(InFuzzingThread());
- // We copy the contents of Unit into a separate heap buffer
- // so that we reliably find buffer overflows in it.
- uint8_t *DataCopy = new uint8_t[Size];
- memcpy(DataCopy, Data, Size);
- if (EF->__msan_unpoison)
- EF->__msan_unpoison(DataCopy, Size);
- if (EF->__msan_unpoison_param)
- EF->__msan_unpoison_param(2);
- if (CurrentUnitData && CurrentUnitData != Data)
- memcpy(CurrentUnitData, Data, Size);
- CurrentUnitSize = Size;
- {
- ScopedEnableMsanInterceptorChecks S;
- AllocTracer.Start(Options.TraceMalloc);
- UnitStartTime = system_clock::now();
- TPC.ResetMaps();
- RunningUserCallback = true;
- int Res = CB(DataCopy, Size);
- RunningUserCallback = false;
- UnitStopTime = system_clock::now();
- (void)Res;
- assert(Res == 0);
- HasMoreMallocsThanFrees = AllocTracer.Stop();
- }
- if (!LooseMemeq(DataCopy, Data, Size))
- CrashOnOverwrittenData();
- CurrentUnitSize = 0;
- delete[] DataCopy;
-}
-
-std::string Fuzzer::WriteToOutputCorpus(const Unit &U) {
- if (Options.OnlyASCII)
- assert(IsASCII(U));
- if (Options.OutputCorpus.empty())
- return "";
- std::string Path = DirPlusFile(Options.OutputCorpus, Hash(U));
- WriteToFile(U, Path);
- if (Options.Verbosity >= 2)
- Printf("Written %zd bytes to %s\n", U.size(), Path.c_str());
- return Path;
-}
-
-void Fuzzer::WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix) {
- if (!Options.SaveArtifacts)
- return;
- std::string Path = Options.ArtifactPrefix + Prefix + Hash(U);
- if (!Options.ExactArtifactPath.empty())
- Path = Options.ExactArtifactPath; // Overrides ArtifactPrefix.
- WriteToFile(U, Path);
- Printf("artifact_prefix='%s'; Test unit written to %s\n",
- Options.ArtifactPrefix.c_str(), Path.c_str());
- if (U.size() <= kMaxUnitSizeToPrint)
- Printf("Base64: %s\n", Base64(U).c_str());
-}
-
-void Fuzzer::PrintStatusForNewUnit(const Unit &U, const char *Text) {
- if (!Options.PrintNEW)
- return;
- PrintStats(Text, "");
- if (Options.Verbosity) {
- Printf(" L: %zd/%zd ", U.size(), Corpus.MaxInputSize());
- MD.PrintMutationSequence(Options.Verbosity >= 2);
- Printf("\n");
- }
-}
-
-void Fuzzer::ReportNewCoverage(InputInfo *II, const Unit &U) {
- II->NumSuccessfullMutations++;
- MD.RecordSuccessfulMutationSequence();
- PrintStatusForNewUnit(U, II->Reduced ? "REDUCE" : "NEW ");
- WriteToOutputCorpus(U);
- NumberOfNewUnitsAdded++;
- CheckExitOnSrcPosOrItem(); // Check only after the unit is saved to corpus.
- LastCorpusUpdateRun = TotalNumberOfRuns;
-}
-
-// Tries detecting a memory leak on the particular input that we have just
-// executed before calling this function.
-void Fuzzer::TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
- bool DuringInitialCorpusExecution) {
- if (!HasMoreMallocsThanFrees)
- return; // mallocs==frees, a leak is unlikely.
- if (!Options.DetectLeaks)
- return;
- if (!DuringInitialCorpusExecution &&
- TotalNumberOfRuns >= Options.MaxNumberOfRuns)
- return;
- if (!&(EF->__lsan_enable) || !&(EF->__lsan_disable) ||
- !(EF->__lsan_do_recoverable_leak_check))
- return; // No lsan.
- // Run the target once again, but with lsan disabled so that if there is
- // a real leak we do not report it twice.
- EF->__lsan_disable();
- ExecuteCallback(Data, Size);
- EF->__lsan_enable();
- if (!HasMoreMallocsThanFrees)
- return; // a leak is unlikely.
- if (NumberOfLeakDetectionAttempts++ > 1000) {
- Options.DetectLeaks = false;
- Printf("INFO: libFuzzer disabled leak detection after every mutation.\n"
- " Most likely the target function accumulates allocated\n"
- " memory in a global state w/o actually leaking it.\n"
- " You may try running this binary with -trace_malloc=[12]"
- " to get a trace of mallocs and frees.\n"
- " If LeakSanitizer is enabled in this process it will still\n"
- " run on the process shutdown.\n");
- return;
- }
- // Now perform the actual lsan pass. This is expensive and we must ensure
- // we don't call it too often.
- if (EF->__lsan_do_recoverable_leak_check()) { // Leak is found, report it.
- if (DuringInitialCorpusExecution)
- Printf("\nINFO: a leak has been found in the initial corpus.\n\n");
- Printf("INFO: to ignore leaks on libFuzzer side use -detect_leaks=0.\n\n");
- CurrentUnitSize = Size;
- DumpCurrentUnit("leak-");
- PrintFinalStats();
- _Exit(Options.ErrorExitCode); // not exit() to disable lsan further on.
- }
-}
-
-void Fuzzer::MutateAndTestOne() {
- MD.StartMutationSequence();
-
- auto &II = Corpus.ChooseUnitToMutate(MD.GetRand());
- if (Options.DoCrossOver) {
- auto &CrossOverII = Corpus.ChooseUnitToCrossOverWith(
- MD.GetRand(), Options.CrossOverUniformDist);
- MD.SetCrossOverWith(&CrossOverII.U);
- }
- const auto &U = II.U;
- memcpy(BaseSha1, II.Sha1, sizeof(BaseSha1));
- assert(CurrentUnitData);
- size_t Size = U.size();
- assert(Size <= MaxInputLen && "Oversized Unit");
- memcpy(CurrentUnitData, U.data(), Size);
-
- assert(MaxMutationLen > 0);
-
- size_t CurrentMaxMutationLen =
- Min(MaxMutationLen, Max(U.size(), TmpMaxMutationLen));
- assert(CurrentMaxMutationLen > 0);
-
- for (int i = 0; i < Options.MutateDepth; i++) {
- if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
- break;
- MaybeExitGracefully();
- size_t NewSize = 0;
- if (II.HasFocusFunction && !II.DataFlowTraceForFocusFunction.empty() &&
- Size <= CurrentMaxMutationLen)
- NewSize = MD.MutateWithMask(CurrentUnitData, Size, Size,
- II.DataFlowTraceForFocusFunction);
-
- // If MutateWithMask either failed or wasn't called, call default Mutate.
- if (!NewSize)
- NewSize = MD.Mutate(CurrentUnitData, Size, CurrentMaxMutationLen);
- assert(NewSize > 0 && "Mutator returned empty unit");
- assert(NewSize <= CurrentMaxMutationLen && "Mutator return oversized unit");
- Size = NewSize;
- II.NumExecutedMutations++;
- Corpus.IncrementNumExecutedMutations();
-
- bool FoundUniqFeatures = false;
- bool NewCov = RunOne(CurrentUnitData, Size, /*MayDeleteFile=*/true, &II,
- /*ForceAddToCorpus*/ false, &FoundUniqFeatures);
- TryDetectingAMemoryLeak(CurrentUnitData, Size,
- /*DuringInitialCorpusExecution*/ false);
- if (NewCov) {
- ReportNewCoverage(&II, {CurrentUnitData, CurrentUnitData + Size});
- break; // We will mutate this input more in the next rounds.
- }
- if (Options.ReduceDepth && !FoundUniqFeatures)
- break;
- }
-
- II.NeedsEnergyUpdate = true;
-}
-
-void Fuzzer::PurgeAllocator() {
- if (Options.PurgeAllocatorIntervalSec < 0 || !EF->__sanitizer_purge_allocator)
- return;
- if (duration_cast<seconds>(system_clock::now() -
- LastAllocatorPurgeAttemptTime)
- .count() < Options.PurgeAllocatorIntervalSec)
- return;
-
- if (Options.RssLimitMb <= 0 ||
- GetPeakRSSMb() > static_cast<size_t>(Options.RssLimitMb) / 2)
- EF->__sanitizer_purge_allocator();
-
- LastAllocatorPurgeAttemptTime = system_clock::now();
-}
-
-void Fuzzer::ReadAndExecuteSeedCorpora(Vector<SizedFile> &CorporaFiles) {
- const size_t kMaxSaneLen = 1 << 20;
- const size_t kMinDefaultLen = 4096;
- size_t MaxSize = 0;
- size_t MinSize = -1;
- size_t TotalSize = 0;
- for (auto &File : CorporaFiles) {
- MaxSize = Max(File.Size, MaxSize);
- MinSize = Min(File.Size, MinSize);
- TotalSize += File.Size;
- }
- if (Options.MaxLen == 0)
- SetMaxInputLen(std::min(std::max(kMinDefaultLen, MaxSize), kMaxSaneLen));
- assert(MaxInputLen > 0);
-
- // Test the callback with empty input and never try it again.
- uint8_t dummy = 0;
- ExecuteCallback(&dummy, 0);
-
- if (CorporaFiles.empty()) {
- Printf("INFO: A corpus is not provided, starting from an empty corpus\n");
- Unit U({'\n'}); // Valid ASCII input.
- RunOne(U.data(), U.size());
- } else {
- Printf("INFO: seed corpus: files: %zd min: %zdb max: %zdb total: %zdb"
- " rss: %zdMb\n",
- CorporaFiles.size(), MinSize, MaxSize, TotalSize, GetPeakRSSMb());
- if (Options.ShuffleAtStartUp)
- std::shuffle(CorporaFiles.begin(), CorporaFiles.end(), MD.GetRand());
-
- if (Options.PreferSmall) {
- std::stable_sort(CorporaFiles.begin(), CorporaFiles.end());
- assert(CorporaFiles.front().Size <= CorporaFiles.back().Size);
- }
-
- // Load and execute inputs one by one.
- for (auto &SF : CorporaFiles) {
- auto U = FileToVector(SF.File, MaxInputLen, /*ExitOnError=*/false);
- assert(U.size() <= MaxInputLen);
- RunOne(U.data(), U.size(), /*MayDeleteFile*/ false, /*II*/ nullptr,
- /*ForceAddToCorpus*/ Options.KeepSeed,
- /*FoundUniqFeatures*/ nullptr);
- CheckExitOnSrcPosOrItem();
- TryDetectingAMemoryLeak(U.data(), U.size(),
- /*DuringInitialCorpusExecution*/ true);
- }
- }
-
- PrintStats("INITED");
- if (!Options.FocusFunction.empty()) {
- Printf("INFO: %zd/%zd inputs touch the focus function\n",
- Corpus.NumInputsThatTouchFocusFunction(), Corpus.size());
- if (!Options.DataFlowTrace.empty())
- Printf("INFO: %zd/%zd inputs have the Data Flow Trace\n",
- Corpus.NumInputsWithDataFlowTrace(),
- Corpus.NumInputsThatTouchFocusFunction());
- }
-
- if (Corpus.empty() && Options.MaxNumberOfRuns) {
- Printf("ERROR: no interesting inputs were found. "
- "Is the code instrumented for coverage? Exiting.\n");
- exit(1);
- }
-}
-
-void Fuzzer::Loop(Vector<SizedFile> &CorporaFiles) {
- auto FocusFunctionOrAuto = Options.FocusFunction;
- DFT.Init(Options.DataFlowTrace, &FocusFunctionOrAuto, CorporaFiles,
- MD.GetRand());
- TPC.SetFocusFunction(FocusFunctionOrAuto);
- ReadAndExecuteSeedCorpora(CorporaFiles);
- DFT.Clear(); // No need for DFT any more.
- TPC.SetPrintNewPCs(Options.PrintNewCovPcs);
- TPC.SetPrintNewFuncs(Options.PrintNewCovFuncs);
- system_clock::time_point LastCorpusReload = system_clock::now();
-
- TmpMaxMutationLen =
- Min(MaxMutationLen, Max(size_t(4), Corpus.MaxInputSize()));
-
- while (true) {
- auto Now = system_clock::now();
- if (!Options.StopFile.empty() &&
- !FileToVector(Options.StopFile, 1, false).empty())
- break;
- if (duration_cast<seconds>(Now - LastCorpusReload).count() >=
- Options.ReloadIntervalSec) {
- RereadOutputCorpus(MaxInputLen);
- LastCorpusReload = system_clock::now();
- }
- if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
- break;
- if (TimedOut())
- break;
-
- // Update TmpMaxMutationLen
- if (Options.LenControl) {
- if (TmpMaxMutationLen < MaxMutationLen &&
- TotalNumberOfRuns - LastCorpusUpdateRun >
- Options.LenControl * Log(TmpMaxMutationLen)) {
- TmpMaxMutationLen =
- Min(MaxMutationLen, TmpMaxMutationLen + Log(TmpMaxMutationLen));
- LastCorpusUpdateRun = TotalNumberOfRuns;
- }
- } else {
- TmpMaxMutationLen = MaxMutationLen;
- }
-
- // Perform several mutations and runs.
- MutateAndTestOne();
-
- PurgeAllocator();
- }
-
- PrintStats("DONE ", "\n");
- MD.PrintRecommendedDictionary();
-}
-
-void Fuzzer::MinimizeCrashLoop(const Unit &U) {
- if (U.size() <= 1)
- return;
- while (!TimedOut() && TotalNumberOfRuns < Options.MaxNumberOfRuns) {
- MD.StartMutationSequence();
- memcpy(CurrentUnitData, U.data(), U.size());
- for (int i = 0; i < Options.MutateDepth; i++) {
- size_t NewSize = MD.Mutate(CurrentUnitData, U.size(), MaxMutationLen);
- assert(NewSize > 0 && NewSize <= MaxMutationLen);
- ExecuteCallback(CurrentUnitData, NewSize);
- PrintPulseAndReportSlowInput(CurrentUnitData, NewSize);
- TryDetectingAMemoryLeak(CurrentUnitData, NewSize,
- /*DuringInitialCorpusExecution*/ false);
- }
- }
-}
-
-} // namespace fuzzer
-
-extern "C" {
-
-ATTRIBUTE_INTERFACE size_t
-LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) {
- assert(fuzzer::F);
- return fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);
-}
-
-} // extern "C"
diff --git a/contrib/libs/libfuzzer12/FuzzerMain.cpp b/contrib/libs/libfuzzer12/FuzzerMain.cpp
deleted file mode 100644
index 75f2f8e75c9..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerMain.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-//===- FuzzerMain.cpp - main() function and flags -------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// main() and flags.
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerDefs.h"
-#include "FuzzerPlatform.h"
-
-extern "C" {
-// This function should be defined by the user.
-int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
-} // extern "C"
-
-ATTRIBUTE_INTERFACE int main(int argc, char **argv) {
- return fuzzer::FuzzerDriver(&argc, &argv, LLVMFuzzerTestOneInput);
-}
diff --git a/contrib/libs/libfuzzer12/FuzzerMerge.cpp b/contrib/libs/libfuzzer12/FuzzerMerge.cpp
deleted file mode 100644
index e3ad8b3851e..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerMerge.cpp
+++ /dev/null
@@ -1,402 +0,0 @@
-//===- FuzzerMerge.cpp - merging corpora ----------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Merging corpora.
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerCommand.h"
-#include "FuzzerMerge.h"
-#include "FuzzerIO.h"
-#include "FuzzerInternal.h"
-#include "FuzzerTracePC.h"
-#include "FuzzerUtil.h"
-
-#include <fstream>
-#include <iterator>
-#include <set>
-#include <sstream>
-#include <unordered_set>
-
-namespace fuzzer {
-
-bool Merger::Parse(const std::string &Str, bool ParseCoverage) {
- std::istringstream SS(Str);
- return Parse(SS, ParseCoverage);
-}
-
-void Merger::ParseOrExit(std::istream &IS, bool ParseCoverage) {
- if (!Parse(IS, ParseCoverage)) {
- Printf("MERGE: failed to parse the control file (unexpected error)\n");
- exit(1);
- }
-}
-
-// The control file example:
-//
-// 3 # The number of inputs
-// 1 # The number of inputs in the first corpus, <= the previous number
-// file0
-// file1
-// file2 # One file name per line.
-// STARTED 0 123 # FileID, file size
-// FT 0 1 4 6 8 # FileID COV1 COV2 ...
-// COV 0 7 8 9 # FileID COV1 COV1
-// STARTED 1 456 # If FT is missing, the input crashed while processing.
-// STARTED 2 567
-// FT 2 8 9
-// COV 2 11 12
-bool Merger::Parse(std::istream &IS, bool ParseCoverage) {
- LastFailure.clear();
- std::string Line;
-
- // Parse NumFiles.
- if (!std::getline(IS, Line, '\n')) return false;
- std::istringstream L1(Line);
- size_t NumFiles = 0;
- L1 >> NumFiles;
- if (NumFiles == 0 || NumFiles > 10000000) return false;
-
- // Parse NumFilesInFirstCorpus.
- if (!std::getline(IS, Line, '\n')) return false;
- std::istringstream L2(Line);
- NumFilesInFirstCorpus = NumFiles + 1;
- L2 >> NumFilesInFirstCorpus;
- if (NumFilesInFirstCorpus > NumFiles) return false;
-
- // Parse file names.
- Files.resize(NumFiles);
- for (size_t i = 0; i < NumFiles; i++)
- if (!std::getline(IS, Files[i].Name, '\n'))
- return false;
-
- // Parse STARTED, FT, and COV lines.
- size_t ExpectedStartMarker = 0;
- const size_t kInvalidStartMarker = -1;
- size_t LastSeenStartMarker = kInvalidStartMarker;
- Vector<uint32_t> TmpFeatures;
- Set<uint32_t> PCs;
- while (std::getline(IS, Line, '\n')) {
- std::istringstream ISS1(Line);
- std::string Marker;
- size_t N;
- ISS1 >> Marker;
- ISS1 >> N;
- if (Marker == "STARTED") {
- // STARTED FILE_ID FILE_SIZE
- if (ExpectedStartMarker != N)
- return false;
- ISS1 >> Files[ExpectedStartMarker].Size;
- LastSeenStartMarker = ExpectedStartMarker;
- assert(ExpectedStartMarker < Files.size());
- ExpectedStartMarker++;
- } else if (Marker == "FT") {
- // FT FILE_ID COV1 COV2 COV3 ...
- size_t CurrentFileIdx = N;
- if (CurrentFileIdx != LastSeenStartMarker)
- return false;
- LastSeenStartMarker = kInvalidStartMarker;
- if (ParseCoverage) {
- TmpFeatures.clear(); // use a vector from outer scope to avoid resizes.
- while (ISS1 >> N)
- TmpFeatures.push_back(N);
- std::sort(TmpFeatures.begin(), TmpFeatures.end());
- Files[CurrentFileIdx].Features = TmpFeatures;
- }
- } else if (Marker == "COV") {
- size_t CurrentFileIdx = N;
- if (ParseCoverage)
- while (ISS1 >> N)
- if (PCs.insert(N).second)
- Files[CurrentFileIdx].Cov.push_back(N);
- } else {
- return false;
- }
- }
- if (LastSeenStartMarker != kInvalidStartMarker)
- LastFailure = Files[LastSeenStartMarker].Name;
-
- FirstNotProcessedFile = ExpectedStartMarker;
- return true;
-}
-
-size_t Merger::ApproximateMemoryConsumption() const {
- size_t Res = 0;
- for (const auto &F: Files)
- Res += sizeof(F) + F.Features.size() * sizeof(F.Features[0]);
- return Res;
-}
-
-// Decides which files need to be merged (add those to NewFiles).
-// Returns the number of new features added.
-size_t Merger::Merge(const Set<uint32_t> &InitialFeatures,
- Set<uint32_t> *NewFeatures,
- const Set<uint32_t> &InitialCov, Set<uint32_t> *NewCov,
- Vector<std::string> *NewFiles) {
- NewFiles->clear();
- assert(NumFilesInFirstCorpus <= Files.size());
- Set<uint32_t> AllFeatures = InitialFeatures;
-
- // What features are in the initial corpus?
- for (size_t i = 0; i < NumFilesInFirstCorpus; i++) {
- auto &Cur = Files[i].Features;
- AllFeatures.insert(Cur.begin(), Cur.end());
- }
- // Remove all features that we already know from all other inputs.
- for (size_t i = NumFilesInFirstCorpus; i < Files.size(); i++) {
- auto &Cur = Files[i].Features;
- Vector<uint32_t> Tmp;
- std::set_difference(Cur.begin(), Cur.end(), AllFeatures.begin(),
- AllFeatures.end(), std::inserter(Tmp, Tmp.begin()));
- Cur.swap(Tmp);
- }
-
- // Sort. Give preference to
- // * smaller files
- // * files with more features.
- std::sort(Files.begin() + NumFilesInFirstCorpus, Files.end(),
- [&](const MergeFileInfo &a, const MergeFileInfo &b) -> bool {
- if (a.Size != b.Size)
- return a.Size < b.Size;
- return a.Features.size() > b.Features.size();
- });
-
- // One greedy pass: add the file's features to AllFeatures.
- // If new features were added, add this file to NewFiles.
- for (size_t i = NumFilesInFirstCorpus; i < Files.size(); i++) {
- auto &Cur = Files[i].Features;
- // Printf("%s -> sz %zd ft %zd\n", Files[i].Name.c_str(),
- // Files[i].Size, Cur.size());
- bool FoundNewFeatures = false;
- for (auto Fe: Cur) {
- if (AllFeatures.insert(Fe).second) {
- FoundNewFeatures = true;
- NewFeatures->insert(Fe);
- }
- }
- if (FoundNewFeatures)
- NewFiles->push_back(Files[i].Name);
- for (auto Cov : Files[i].Cov)
- if (InitialCov.find(Cov) == InitialCov.end())
- NewCov->insert(Cov);
- }
- return NewFeatures->size();
-}
-
-Set<uint32_t> Merger::AllFeatures() const {
- Set<uint32_t> S;
- for (auto &File : Files)
- S.insert(File.Features.begin(), File.Features.end());
- return S;
-}
-
-// Inner process. May crash if the target crashes.
-void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) {
- Printf("MERGE-INNER: using the control file '%s'\n", CFPath.c_str());
- Merger M;
- std::ifstream IF(CFPath);
- M.ParseOrExit(IF, false);
- IF.close();
- if (!M.LastFailure.empty())
- Printf("MERGE-INNER: '%s' caused a failure at the previous merge step\n",
- M.LastFailure.c_str());
-
- Printf("MERGE-INNER: %zd total files;"
- " %zd processed earlier; will process %zd files now\n",
- M.Files.size(), M.FirstNotProcessedFile,
- M.Files.size() - M.FirstNotProcessedFile);
-
- std::ofstream OF(CFPath, std::ofstream::out | std::ofstream::app);
- Set<size_t> AllFeatures;
- auto PrintStatsWrapper = [this, &AllFeatures](const char* Where) {
- this->PrintStats(Where, "\n", 0, AllFeatures.size());
- };
- Set<const TracePC::PCTableEntry *> AllPCs;
- for (size_t i = M.FirstNotProcessedFile; i < M.Files.size(); i++) {
- Fuzzer::MaybeExitGracefully();
- auto U = FileToVector(M.Files[i].Name);
- if (U.size() > MaxInputLen) {
- U.resize(MaxInputLen);
- U.shrink_to_fit();
- }
-
- // Write the pre-run marker.
- OF << "STARTED " << i << " " << U.size() << "\n";
- OF.flush(); // Flush is important since Command::Execute may crash.
- // Run.
- TPC.ResetMaps();
- ExecuteCallback(U.data(), U.size());
- // Collect coverage. We are iterating over the files in this order:
- // * First, files in the initial corpus ordered by size, smallest first.
- // * Then, all other files, smallest first.
- // So it makes no sense to record all features for all files, instead we
- // only record features that were not seen before.
- Set<size_t> UniqFeatures;
- TPC.CollectFeatures([&](size_t Feature) {
- if (AllFeatures.insert(Feature).second)
- UniqFeatures.insert(Feature);
- });
- TPC.UpdateObservedPCs();
- // Show stats.
- if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1)))
- PrintStatsWrapper("pulse ");
- if (TotalNumberOfRuns == M.NumFilesInFirstCorpus)
- PrintStatsWrapper("LOADED");
- // Write the post-run marker and the coverage.
- OF << "FT " << i;
- for (size_t F : UniqFeatures)
- OF << " " << F;
- OF << "\n";
- OF << "COV " << i;
- TPC.ForEachObservedPC([&](const TracePC::PCTableEntry *TE) {
- if (AllPCs.insert(TE).second)
- OF << " " << TPC.PCTableEntryIdx(TE);
- });
- OF << "\n";
- OF.flush();
- }
- PrintStatsWrapper("DONE ");
-}
-
-static size_t WriteNewControlFile(const std::string &CFPath,
- const Vector<SizedFile> &OldCorpus,
- const Vector<SizedFile> &NewCorpus,
- const Vector<MergeFileInfo> &KnownFiles) {
- std::unordered_set<std::string> FilesToSkip;
- for (auto &SF: KnownFiles)
- FilesToSkip.insert(SF.Name);
-
- Vector<std::string> FilesToUse;
- auto MaybeUseFile = [=, &FilesToUse](std::string Name) {
- if (FilesToSkip.find(Name) == FilesToSkip.end())
- FilesToUse.push_back(Name);
- };
- for (auto &SF: OldCorpus)
- MaybeUseFile(SF.File);
- auto FilesToUseFromOldCorpus = FilesToUse.size();
- for (auto &SF: NewCorpus)
- MaybeUseFile(SF.File);
-
- RemoveFile(CFPath);
- std::ofstream ControlFile(CFPath);
- ControlFile << FilesToUse.size() << "\n";
- ControlFile << FilesToUseFromOldCorpus << "\n";
- for (auto &FN: FilesToUse)
- ControlFile << FN << "\n";
-
- if (!ControlFile) {
- Printf("MERGE-OUTER: failed to write to the control file: %s\n",
- CFPath.c_str());
- exit(1);
- }
-
- return FilesToUse.size();
-}
-
-// Outer process. Does not call the target code and thus should not fail.
-void CrashResistantMerge(const Vector<std::string> &Args,
- const Vector<SizedFile> &OldCorpus,
- const Vector<SizedFile> &NewCorpus,
- Vector<std::string> *NewFiles,
- const Set<uint32_t> &InitialFeatures,
- Set<uint32_t> *NewFeatures,
- const Set<uint32_t> &InitialCov,
- Set<uint32_t> *NewCov,
- const std::string &CFPath,
- bool V /*Verbose*/) {
- if (NewCorpus.empty() && OldCorpus.empty()) return; // Nothing to merge.
- size_t NumAttempts = 0;
- Vector<MergeFileInfo> KnownFiles;
- if (FileSize(CFPath)) {
- VPrintf(V, "MERGE-OUTER: non-empty control file provided: '%s'\n",
- CFPath.c_str());
- Merger M;
- std::ifstream IF(CFPath);
- if (M.Parse(IF, /*ParseCoverage=*/true)) {
- VPrintf(V, "MERGE-OUTER: control file ok, %zd files total,"
- " first not processed file %zd\n",
- M.Files.size(), M.FirstNotProcessedFile);
- if (!M.LastFailure.empty())
- VPrintf(V, "MERGE-OUTER: '%s' will be skipped as unlucky "
- "(merge has stumbled on it the last time)\n",
- M.LastFailure.c_str());
- if (M.FirstNotProcessedFile >= M.Files.size()) {
- // Merge has already been completed with the given merge control file.
- if (M.Files.size() == OldCorpus.size() + NewCorpus.size()) {
- VPrintf(
- V,
- "MERGE-OUTER: nothing to do, merge has been completed before\n");
- exit(0);
- }
-
- // Number of input files likely changed, start merge from scratch, but
- // reuse coverage information from the given merge control file.
- VPrintf(
- V,
- "MERGE-OUTER: starting merge from scratch, but reusing coverage "
- "information from the given control file\n");
- KnownFiles = M.Files;
- } else {
- // There is a merge in progress, continue.
- NumAttempts = M.Files.size() - M.FirstNotProcessedFile;
- }
- } else {
- VPrintf(V, "MERGE-OUTER: bad control file, will overwrite it\n");
- }
- }
-
- if (!NumAttempts) {
- // The supplied control file is empty or bad, create a fresh one.
- VPrintf(V, "MERGE-OUTER: "
- "%zd files, %zd in the initial corpus, %zd processed earlier\n",
- OldCorpus.size() + NewCorpus.size(), OldCorpus.size(),
- KnownFiles.size());
- NumAttempts = WriteNewControlFile(CFPath, OldCorpus, NewCorpus, KnownFiles);
- }
-
- // Execute the inner process until it passes.
- // Every inner process should execute at least one input.
- Command BaseCmd(Args);
- BaseCmd.removeFlag("merge");
- BaseCmd.removeFlag("fork");
- BaseCmd.removeFlag("collect_data_flow");
- for (size_t Attempt = 1; Attempt <= NumAttempts; Attempt++) {
- Fuzzer::MaybeExitGracefully();
- VPrintf(V, "MERGE-OUTER: attempt %zd\n", Attempt);
- Command Cmd(BaseCmd);
- Cmd.addFlag("merge_control_file", CFPath);
- Cmd.addFlag("merge_inner", "1");
- if (!V) {
- Cmd.setOutputFile(getDevNull());
- Cmd.combineOutAndErr();
- }
- auto ExitCode = ExecuteCommand(Cmd);
- if (!ExitCode) {
- VPrintf(V, "MERGE-OUTER: succesfull in %zd attempt(s)\n", Attempt);
- break;
- }
- }
- // Read the control file and do the merge.
- Merger M;
- std::ifstream IF(CFPath);
- IF.seekg(0, IF.end);
- VPrintf(V, "MERGE-OUTER: the control file has %zd bytes\n",
- (size_t)IF.tellg());
- IF.seekg(0, IF.beg);
- M.ParseOrExit(IF, true);
- IF.close();
- VPrintf(V,
- "MERGE-OUTER: consumed %zdMb (%zdMb rss) to parse the control file\n",
- M.ApproximateMemoryConsumption() >> 20, GetPeakRSSMb());
-
- M.Files.insert(M.Files.end(), KnownFiles.begin(), KnownFiles.end());
- M.Merge(InitialFeatures, NewFeatures, InitialCov, NewCov, NewFiles);
- VPrintf(V, "MERGE-OUTER: %zd new files with %zd new features added; "
- "%zd new coverage edges\n",
- NewFiles->size(), NewFeatures->size(), NewCov->size());
-}
-
-} // namespace fuzzer
diff --git a/contrib/libs/libfuzzer12/FuzzerMerge.h b/contrib/libs/libfuzzer12/FuzzerMerge.h
deleted file mode 100644
index e0c6bc539bd..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerMerge.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//===- FuzzerMerge.h - merging corpa ----------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-// Merging Corpora.
-//
-// The task:
-// Take the existing corpus (possibly empty) and merge new inputs into
-// it so that only inputs with new coverage ('features') are added.
-// The process should tolerate the crashes, OOMs, leaks, etc.
-//
-// Algorithm:
-// The outer process collects the set of files and writes their names
-// into a temporary "control" file, then repeatedly launches the inner
-// process until all inputs are processed.
-// The outer process does not actually execute the target code.
-//
-// The inner process reads the control file and sees a) list of all the inputs
-// and b) the last processed input. Then it starts processing the inputs one
-// by one. Before processing every input it writes one line to control file:
-// STARTED INPUT_ID INPUT_SIZE
-// After processing an input it writes the following lines:
-// FT INPUT_ID Feature1 Feature2 Feature3 ...
-// COV INPUT_ID Coverage1 Coverage2 Coverage3 ...
-// If a crash happens while processing an input the last line in the control
-// file will be "STARTED INPUT_ID" and so the next process will know
-// where to resume.
-//
-// Once all inputs are processed by the inner process(es) the outer process
-// reads the control files and does the merge based entirely on the contents
-// of control file.
-// It uses a single pass greedy algorithm choosing first the smallest inputs
-// within the same size the inputs that have more new features.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_MERGE_H
-#define LLVM_FUZZER_MERGE_H
-
-#include "FuzzerDefs.h"
-
-#include <istream>
-#include <ostream>
-#include <set>
-#include <vector>
-
-namespace fuzzer {
-
-struct MergeFileInfo {
- std::string Name;
- size_t Size = 0;
- Vector<uint32_t> Features, Cov;
-};
-
-struct Merger {
- Vector<MergeFileInfo> Files;
- size_t NumFilesInFirstCorpus = 0;
- size_t FirstNotProcessedFile = 0;
- std::string LastFailure;
-
- bool Parse(std::istream &IS, bool ParseCoverage);
- bool Parse(const std::string &Str, bool ParseCoverage);
- void ParseOrExit(std::istream &IS, bool ParseCoverage);
- size_t Merge(const Set<uint32_t> &InitialFeatures, Set<uint32_t> *NewFeatures,
- const Set<uint32_t> &InitialCov, Set<uint32_t> *NewCov,
- Vector<std::string> *NewFiles);
- size_t ApproximateMemoryConsumption() const;
- Set<uint32_t> AllFeatures() const;
-};
-
-void CrashResistantMerge(const Vector<std::string> &Args,
- const Vector<SizedFile> &OldCorpus,
- const Vector<SizedFile> &NewCorpus,
- Vector<std::string> *NewFiles,
- const Set<uint32_t> &InitialFeatures,
- Set<uint32_t> *NewFeatures,
- const Set<uint32_t> &InitialCov,
- Set<uint32_t> *NewCov,
- const std::string &CFPath,
- bool Verbose);
-
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_MERGE_H
diff --git a/contrib/libs/libfuzzer12/FuzzerMutate.cpp b/contrib/libs/libfuzzer12/FuzzerMutate.cpp
deleted file mode 100644
index cf34a9fe8e2..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerMutate.cpp
+++ /dev/null
@@ -1,578 +0,0 @@
-//===- FuzzerMutate.cpp - Mutate a test input -----------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Mutate a test input.
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerDefs.h"
-#include "FuzzerExtFunctions.h"
-#include "FuzzerIO.h"
-#include "FuzzerMutate.h"
-#include "FuzzerOptions.h"
-#include "FuzzerTracePC.h"
-
-namespace fuzzer {
-
-const size_t Dictionary::kMaxDictSize;
-static const size_t kMaxMutationsToPrint = 10;
-
-static void PrintASCII(const Word &W, const char *PrintAfter) {
- PrintASCII(W.data(), W.size(), PrintAfter);
-}
-
-MutationDispatcher::MutationDispatcher(Random &Rand,
- const FuzzingOptions &Options)
- : Rand(Rand), Options(Options) {
- DefaultMutators.insert(
- DefaultMutators.begin(),
- {
- {&MutationDispatcher::Mutate_EraseBytes, "EraseBytes"},
- {&MutationDispatcher::Mutate_InsertByte, "InsertByte"},
- {&MutationDispatcher::Mutate_InsertRepeatedBytes,
- "InsertRepeatedBytes"},
- {&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"},
- {&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
- {&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
- {&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"},
- {&MutationDispatcher::Mutate_ChangeBinaryInteger, "ChangeBinInt"},
- {&MutationDispatcher::Mutate_CopyPart, "CopyPart"},
- {&MutationDispatcher::Mutate_CrossOver, "CrossOver"},
- {&MutationDispatcher::Mutate_AddWordFromManualDictionary,
- "ManualDict"},
- {&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
- "PersAutoDict"},
- });
- if(Options.UseCmp)
- DefaultMutators.push_back(
- {&MutationDispatcher::Mutate_AddWordFromTORC, "CMP"});
-
- if (EF->LLVMFuzzerCustomMutator)
- Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom"});
- else
- Mutators = DefaultMutators;
-
- if (EF->LLVMFuzzerCustomCrossOver)
- Mutators.push_back(
- {&MutationDispatcher::Mutate_CustomCrossOver, "CustomCrossOver"});
-}
-
-static char RandCh(Random &Rand) {
- if (Rand.RandBool()) return Rand(256);
- const char Special[] = "!*'();:@&=+$,/?%#[]012Az-`~.\xff\x00";
- return Special[Rand(sizeof(Special) - 1)];
-}
-
-size_t MutationDispatcher::Mutate_Custom(uint8_t *Data, size_t Size,
- size_t MaxSize) {
- return EF->LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand());
-}
-
-size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size,
- size_t MaxSize) {
- if (Size == 0)
- return 0;
- if (!CrossOverWith) return 0;
- const Unit &Other = *CrossOverWith;
- if (Other.empty())
- return 0;
- CustomCrossOverInPlaceHere.resize(MaxSize);
- auto &U = CustomCrossOverInPlaceHere;
- size_t NewSize = EF->LLVMFuzzerCustomCrossOver(
- Data, Size, Other.data(), Other.size(), U.data(), U.size(), Rand.Rand());
- if (!NewSize)
- return 0;
- assert(NewSize <= MaxSize && "CustomCrossOver returned overisized unit");
- memcpy(Data, U.data(), NewSize);
- return NewSize;
-}
-
-size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
- size_t MaxSize) {
- if (Size > MaxSize || Size == 0) return 0;
- size_t ShuffleAmount =
- Rand(std::min(Size, (size_t)8)) + 1; // [1,8] and <= Size.
- size_t ShuffleStart = Rand(Size - ShuffleAmount);
- assert(ShuffleStart + ShuffleAmount <= Size);
- std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, Rand);
- return Size;
-}
-
-size_t MutationDispatcher::Mutate_EraseBytes(uint8_t *Data, size_t Size,
- size_t MaxSize) {
- if (Size <= 1) return 0;
- size_t N = Rand(Size / 2) + 1;
- assert(N < Size);
- size_t Idx = Rand(Size - N + 1);
- // Erase Data[Idx:Idx+N].
- memmove(Data + Idx, Data + Idx + N, Size - Idx - N);
- // Printf("Erase: %zd %zd => %zd; Idx %zd\n", N, Size, Size - N, Idx);
- return Size - N;
-}
-
-size_t MutationDispatcher::Mutate_InsertByte(uint8_t *Data, size_t Size,
- size_t MaxSize) {
- if (Size >= MaxSize) return 0;
- size_t Idx = Rand(Size + 1);
- // Insert new value at Data[Idx].
- memmove(Data + Idx + 1, Data + Idx, Size - Idx);
- Data[Idx] = RandCh(Rand);
- return Size + 1;
-}
-
-size_t MutationDispatcher::Mutate_InsertRepeatedBytes(uint8_t *Data,
- size_t Size,
- size_t MaxSize) {
- const size_t kMinBytesToInsert = 3;
- if (Size + kMinBytesToInsert >= MaxSize) return 0;
- size_t MaxBytesToInsert = std::min(MaxSize - Size, (size_t)128);
- size_t N = Rand(MaxBytesToInsert - kMinBytesToInsert + 1) + kMinBytesToInsert;
- assert(Size + N <= MaxSize && N);
- size_t Idx = Rand(Size + 1);
- // Insert new values at Data[Idx].
- memmove(Data + Idx + N, Data + Idx, Size - Idx);
- // Give preference to 0x00 and 0xff.
- uint8_t Byte = Rand.RandBool() ? Rand(256) : (Rand.RandBool() ? 0 : 255);
- for (size_t i = 0; i < N; i++)
- Data[Idx + i] = Byte;
- return Size + N;
-}
-
-size_t MutationDispatcher::Mutate_ChangeByte(uint8_t *Data, size_t Size,
- size_t MaxSize) {
- if (Size > MaxSize) return 0;
- size_t Idx = Rand(Size);
- Data[Idx] = RandCh(Rand);
- return Size;
-}
-
-size_t MutationDispatcher::Mutate_ChangeBit(uint8_t *Data, size_t Size,
- size_t MaxSize) {
- if (Size > MaxSize) return 0;
- size_t Idx = Rand(Size);
- Data[Idx] ^= 1 << Rand(8);
- return Size;
-}
-
-size_t MutationDispatcher::Mutate_AddWordFromManualDictionary(uint8_t *Data,
- size_t Size,
- size_t MaxSize) {
- return AddWordFromDictionary(ManualDictionary, Data, Size, MaxSize);
-}
-
-size_t MutationDispatcher::ApplyDictionaryEntry(uint8_t *Data, size_t Size,
- size_t MaxSize,
- DictionaryEntry &DE) {
- const Word &W = DE.GetW();
- bool UsePositionHint = DE.HasPositionHint() &&
- DE.GetPositionHint() + W.size() < Size &&
- Rand.RandBool();
- if (Rand.RandBool()) { // Insert W.
- if (Size + W.size() > MaxSize) return 0;
- size_t Idx = UsePositionHint ? DE.GetPositionHint() : Rand(Size + 1);
- memmove(Data + Idx + W.size(), Data + Idx, Size - Idx);
- memcpy(Data + Idx, W.data(), W.size());
- Size += W.size();
- } else { // Overwrite some bytes with W.
- if (W.size() > Size) return 0;
- size_t Idx = UsePositionHint ? DE.GetPositionHint() : Rand(Size - W.size());
- memcpy(Data + Idx, W.data(), W.size());
- }
- return Size;
-}
-
-// Somewhere in the past we have observed a comparison instructions
-// with arguments Arg1 Arg2. This function tries to guess a dictionary
-// entry that will satisfy that comparison.
-// It first tries to find one of the arguments (possibly swapped) in the
-// input and if it succeeds it creates a DE with a position hint.
-// Otherwise it creates a DE with one of the arguments w/o a position hint.
-DictionaryEntry MutationDispatcher::MakeDictionaryEntryFromCMP(
- const void *Arg1, const void *Arg2,
- const void *Arg1Mutation, const void *Arg2Mutation,
- size_t ArgSize, const uint8_t *Data,
- size_t Size) {
- bool HandleFirst = Rand.RandBool();
- const void *ExistingBytes, *DesiredBytes;
- Word W;
- const uint8_t *End = Data + Size;
- for (int Arg = 0; Arg < 2; Arg++) {
- ExistingBytes = HandleFirst ? Arg1 : Arg2;
- DesiredBytes = HandleFirst ? Arg2Mutation : Arg1Mutation;
- HandleFirst = !HandleFirst;
- W.Set(reinterpret_cast<const uint8_t*>(DesiredBytes), ArgSize);
- const size_t kMaxNumPositions = 8;
- size_t Positions[kMaxNumPositions];
- size_t NumPositions = 0;
- for (const uint8_t *Cur = Data;
- Cur < End && NumPositions < kMaxNumPositions; Cur++) {
- Cur =
- (const uint8_t *)SearchMemory(Cur, End - Cur, ExistingBytes, ArgSize);
- if (!Cur) break;
- Positions[NumPositions++] = Cur - Data;
- }
- if (!NumPositions) continue;
- return DictionaryEntry(W, Positions[Rand(NumPositions)]);
- }
- DictionaryEntry DE(W);
- return DE;
-}
-
-
-template <class T>
-DictionaryEntry MutationDispatcher::MakeDictionaryEntryFromCMP(
- T Arg1, T Arg2, const uint8_t *Data, size_t Size) {
- if (Rand.RandBool()) Arg1 = Bswap(Arg1);
- if (Rand.RandBool()) Arg2 = Bswap(Arg2);
- T Arg1Mutation = Arg1 + Rand(-1, 1);
- T Arg2Mutation = Arg2 + Rand(-1, 1);
- return MakeDictionaryEntryFromCMP(&Arg1, &Arg2, &Arg1Mutation, &Arg2Mutation,
- sizeof(Arg1), Data, Size);
-}
-
-DictionaryEntry MutationDispatcher::MakeDictionaryEntryFromCMP(
- const Word &Arg1, const Word &Arg2, const uint8_t *Data, size_t Size) {
- return MakeDictionaryEntryFromCMP(Arg1.data(), Arg2.data(), Arg1.data(),
- Arg2.data(), Arg1.size(), Data, Size);
-}
-
-size_t MutationDispatcher::Mutate_AddWordFromTORC(
- uint8_t *Data, size_t Size, size_t MaxSize) {
- Word W;
- DictionaryEntry DE;
- switch (Rand(4)) {
- case 0: {
- auto X = TPC.TORC8.Get(Rand.Rand());
- DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);
- } break;
- case 1: {
- auto X = TPC.TORC4.Get(Rand.Rand());
- if ((X.A >> 16) == 0 && (X.B >> 16) == 0 && Rand.RandBool())
- DE = MakeDictionaryEntryFromCMP((uint16_t)X.A, (uint16_t)X.B, Data, Size);
- else
- DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);
- } break;
- case 2: {
- auto X = TPC.TORCW.Get(Rand.Rand());
- DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);
- } break;
- case 3: if (Options.UseMemmem) {
- auto X = TPC.MMT.Get(Rand.Rand());
- DE = DictionaryEntry(X);
- } break;
- default:
- assert(0);
- }
- if (!DE.GetW().size()) return 0;
- Size = ApplyDictionaryEntry(Data, Size, MaxSize, DE);
- if (!Size) return 0;
- DictionaryEntry &DERef =
- CmpDictionaryEntriesDeque[CmpDictionaryEntriesDequeIdx++ %
- kCmpDictionaryEntriesDequeSize];
- DERef = DE;
- CurrentDictionaryEntrySequence.push_back(&DERef);
- return Size;
-}
-
-size_t MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary(
- uint8_t *Data, size_t Size, size_t MaxSize) {
- return AddWordFromDictionary(PersistentAutoDictionary, Data, Size, MaxSize);
-}
-
-size_t MutationDispatcher::AddWordFromDictionary(Dictionary &D, uint8_t *Data,
- size_t Size, size_t MaxSize) {
- if (Size > MaxSize) return 0;
- if (D.empty()) return 0;
- DictionaryEntry &DE = D[Rand(D.size())];
- Size = ApplyDictionaryEntry(Data, Size, MaxSize, DE);
- if (!Size) return 0;
- DE.IncUseCount();
- CurrentDictionaryEntrySequence.push_back(&DE);
- return Size;
-}
-
-// Overwrites part of To[0,ToSize) with a part of From[0,FromSize).
-// Returns ToSize.
-size_t MutationDispatcher::CopyPartOf(const uint8_t *From, size_t FromSize,
- uint8_t *To, size_t ToSize) {
- // Copy From[FromBeg, FromBeg + CopySize) into To[ToBeg, ToBeg + CopySize).
- size_t ToBeg = Rand(ToSize);
- size_t CopySize = Rand(ToSize - ToBeg) + 1;
- assert(ToBeg + CopySize <= ToSize);
- CopySize = std::min(CopySize, FromSize);
- size_t FromBeg = Rand(FromSize - CopySize + 1);
- assert(FromBeg + CopySize <= FromSize);
- memmove(To + ToBeg, From + FromBeg, CopySize);
- return ToSize;
-}
-
-// Inserts part of From[0,ToSize) into To.
-// Returns new size of To on success or 0 on failure.
-size_t MutationDispatcher::InsertPartOf(const uint8_t *From, size_t FromSize,
- uint8_t *To, size_t ToSize,
- size_t MaxToSize) {
- if (ToSize >= MaxToSize) return 0;
- size_t AvailableSpace = MaxToSize - ToSize;
- size_t MaxCopySize = std::min(AvailableSpace, FromSize);
- size_t CopySize = Rand(MaxCopySize) + 1;
- size_t FromBeg = Rand(FromSize - CopySize + 1);
- assert(FromBeg + CopySize <= FromSize);
- size_t ToInsertPos = Rand(ToSize + 1);
- assert(ToInsertPos + CopySize <= MaxToSize);
- size_t TailSize = ToSize - ToInsertPos;
- if (To == From) {
- MutateInPlaceHere.resize(MaxToSize);
- memcpy(MutateInPlaceHere.data(), From + FromBeg, CopySize);
- memmove(To + ToInsertPos + CopySize, To + ToInsertPos, TailSize);
- memmove(To + ToInsertPos, MutateInPlaceHere.data(), CopySize);
- } else {
- memmove(To + ToInsertPos + CopySize, To + ToInsertPos, TailSize);
- memmove(To + ToInsertPos, From + FromBeg, CopySize);
- }
- return ToSize + CopySize;
-}
-
-size_t MutationDispatcher::Mutate_CopyPart(uint8_t *Data, size_t Size,
- size_t MaxSize) {
- if (Size > MaxSize || Size == 0) return 0;
- // If Size == MaxSize, `InsertPartOf(...)` will
- // fail so there's no point using it in this case.
- if (Size == MaxSize || Rand.RandBool())
- return CopyPartOf(Data, Size, Data, Size);
- else
- return InsertPartOf(Data, Size, Data, Size, MaxSize);
-}
-
-size_t MutationDispatcher::Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size,
- size_t MaxSize) {
- if (Size > MaxSize) return 0;
- size_t B = Rand(Size);
- while (B < Size && !isdigit(Data[B])) B++;
- if (B == Size) return 0;
- size_t E = B;
- while (E < Size && isdigit(Data[E])) E++;
- assert(B < E);
- // now we have digits in [B, E).
- // strtol and friends don't accept non-zero-teminated data, parse it manually.
- uint64_t Val = Data[B] - '0';
- for (size_t i = B + 1; i < E; i++)
- Val = Val * 10 + Data[i] - '0';
-
- // Mutate the integer value.
- switch(Rand(5)) {
- case 0: Val++; break;
- case 1: Val--; break;
- case 2: Val /= 2; break;
- case 3: Val *= 2; break;
- case 4: Val = Rand(Val * Val); break;
- default: assert(0);
- }
- // Just replace the bytes with the new ones, don't bother moving bytes.
- for (size_t i = B; i < E; i++) {
- size_t Idx = E + B - i - 1;
- assert(Idx >= B && Idx < E);
- Data[Idx] = (Val % 10) + '0';
- Val /= 10;
- }
- return Size;
-}
-
-template<class T>
-size_t ChangeBinaryInteger(uint8_t *Data, size_t Size, Random &Rand) {
- if (Size < sizeof(T)) return 0;
- size_t Off = Rand(Size - sizeof(T) + 1);
- assert(Off + sizeof(T) <= Size);
- T Val;
- if (Off < 64 && !Rand(4)) {
- Val = Size;
- if (Rand.RandBool())
- Val = Bswap(Val);
- } else {
- memcpy(&Val, Data + Off, sizeof(Val));
- T Add = Rand(21);
- Add -= 10;
- if (Rand.RandBool())
- Val = Bswap(T(Bswap(Val) + Add)); // Add assuming different endiannes.
- else
- Val = Val + Add; // Add assuming current endiannes.
- if (Add == 0 || Rand.RandBool()) // Maybe negate.
- Val = -Val;
- }
- memcpy(Data + Off, &Val, sizeof(Val));
- return Size;
-}
-
-size_t MutationDispatcher::Mutate_ChangeBinaryInteger(uint8_t *Data,
- size_t Size,
- size_t MaxSize) {
- if (Size > MaxSize) return 0;
- switch (Rand(4)) {
- case 3: return ChangeBinaryInteger<uint64_t>(Data, Size, Rand);
- case 2: return ChangeBinaryInteger<uint32_t>(Data, Size, Rand);
- case 1: return ChangeBinaryInteger<uint16_t>(Data, Size, Rand);
- case 0: return ChangeBinaryInteger<uint8_t>(Data, Size, Rand);
- default: assert(0);
- }
- return 0;
-}
-
-size_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data, size_t Size,
- size_t MaxSize) {
- if (Size > MaxSize) return 0;
- if (Size == 0) return 0;
- if (!CrossOverWith) return 0;
- const Unit &O = *CrossOverWith;
- if (O.empty()) return 0;
- size_t NewSize = 0;
- switch(Rand(3)) {
- case 0:
- MutateInPlaceHere.resize(MaxSize);
- NewSize = CrossOver(Data, Size, O.data(), O.size(),
- MutateInPlaceHere.data(), MaxSize);
- memcpy(Data, MutateInPlaceHere.data(), NewSize);
- break;
- case 1:
- NewSize = InsertPartOf(O.data(), O.size(), Data, Size, MaxSize);
- if (!NewSize)
- NewSize = CopyPartOf(O.data(), O.size(), Data, Size);
- break;
- case 2:
- NewSize = CopyPartOf(O.data(), O.size(), Data, Size);
- break;
- default: assert(0);
- }
- assert(NewSize > 0 && "CrossOver returned empty unit");
- assert(NewSize <= MaxSize && "CrossOver returned overisized unit");
- return NewSize;
-}
-
-void MutationDispatcher::StartMutationSequence() {
- CurrentMutatorSequence.clear();
- CurrentDictionaryEntrySequence.clear();
-}
-
-// Copy successful dictionary entries to PersistentAutoDictionary.
-void MutationDispatcher::RecordSuccessfulMutationSequence() {
- for (auto DE : CurrentDictionaryEntrySequence) {
- // PersistentAutoDictionary.AddWithSuccessCountOne(DE);
- DE->IncSuccessCount();
- assert(DE->GetW().size());
- // Linear search is fine here as this happens seldom.
- if (!PersistentAutoDictionary.ContainsWord(DE->GetW()))
- PersistentAutoDictionary.push_back({DE->GetW(), 1});
- }
-}
-
-void MutationDispatcher::PrintRecommendedDictionary() {
- Vector<DictionaryEntry> V;
- for (auto &DE : PersistentAutoDictionary)
- if (!ManualDictionary.ContainsWord(DE.GetW()))
- V.push_back(DE);
- if (V.empty()) return;
- Printf("###### Recommended dictionary. ######\n");
- for (auto &DE: V) {
- assert(DE.GetW().size());
- Printf("\"");
- PrintASCII(DE.GetW(), "\"");
- Printf(" # Uses: %zd\n", DE.GetUseCount());
- }
- Printf("###### End of recommended dictionary. ######\n");
-}
-
-void MutationDispatcher::PrintMutationSequence(bool Verbose) {
- Printf("MS: %zd ", CurrentMutatorSequence.size());
- size_t EntriesToPrint =
- Verbose ? CurrentMutatorSequence.size()
- : std::min(kMaxMutationsToPrint, CurrentMutatorSequence.size());
- for (size_t i = 0; i < EntriesToPrint; i++)
- Printf("%s-", CurrentMutatorSequence[i].Name);
- if (!CurrentDictionaryEntrySequence.empty()) {
- Printf(" DE: ");
- EntriesToPrint = Verbose ? CurrentDictionaryEntrySequence.size()
- : std::min(kMaxMutationsToPrint,
- CurrentDictionaryEntrySequence.size());
- for (size_t i = 0; i < EntriesToPrint; i++) {
- Printf("\"");
- PrintASCII(CurrentDictionaryEntrySequence[i]->GetW(), "\"-");
- }
- }
-}
-
-std::string MutationDispatcher::MutationSequence() {
- std::string MS;
- for (auto M : CurrentMutatorSequence) {
- MS += M.Name;
- MS += "-";
- }
- return MS;
-}
-
-size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
- return MutateImpl(Data, Size, MaxSize, Mutators);
-}
-
-size_t MutationDispatcher::DefaultMutate(uint8_t *Data, size_t Size,
- size_t MaxSize) {
- return MutateImpl(Data, Size, MaxSize, DefaultMutators);
-}
-
-// Mutates Data in place, returns new size.
-size_t MutationDispatcher::MutateImpl(uint8_t *Data, size_t Size,
- size_t MaxSize,
- Vector<Mutator> &Mutators) {
- assert(MaxSize > 0);
- // Some mutations may fail (e.g. can't insert more bytes if Size == MaxSize),
- // in which case they will return 0.
- // Try several times before returning un-mutated data.
- for (int Iter = 0; Iter < 100; Iter++) {
- auto M = Mutators[Rand(Mutators.size())];
- size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize);
- if (NewSize && NewSize <= MaxSize) {
- if (Options.OnlyASCII)
- ToASCII(Data, NewSize);
- CurrentMutatorSequence.push_back(M);
- return NewSize;
- }
- }
- *Data = ' ';
- return 1; // Fallback, should not happen frequently.
-}
-
-// Mask represents the set of Data bytes that are worth mutating.
-size_t MutationDispatcher::MutateWithMask(uint8_t *Data, size_t Size,
- size_t MaxSize,
- const Vector<uint8_t> &Mask) {
- size_t MaskedSize = std::min(Size, Mask.size());
- // * Copy the worthy bytes into a temporary array T
- // * Mutate T
- // * Copy T back.
- // This is totally unoptimized.
- auto &T = MutateWithMaskTemp;
- if (T.size() < Size)
- T.resize(Size);
- size_t OneBits = 0;
- for (size_t I = 0; I < MaskedSize; I++)
- if (Mask[I])
- T[OneBits++] = Data[I];
-
- if (!OneBits) return 0;
- assert(!T.empty());
- size_t NewSize = Mutate(T.data(), OneBits, OneBits);
- assert(NewSize <= OneBits);
- (void)NewSize;
- // Even if NewSize < OneBits we still use all OneBits bytes.
- for (size_t I = 0, J = 0; I < MaskedSize; I++)
- if (Mask[I])
- Data[I] = T[J++];
- return Size;
-}
-
-void MutationDispatcher::AddWordToManualDictionary(const Word &W) {
- ManualDictionary.push_back(
- {W, std::numeric_limits<size_t>::max()});
-}
-
-} // namespace fuzzer
diff --git a/contrib/libs/libfuzzer12/FuzzerMutate.h b/contrib/libs/libfuzzer12/FuzzerMutate.h
deleted file mode 100644
index fd37191156d..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerMutate.h
+++ /dev/null
@@ -1,156 +0,0 @@
-//===- FuzzerMutate.h - Internal header for the Fuzzer ----------*- 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
-//
-//===----------------------------------------------------------------------===//
-// fuzzer::MutationDispatcher
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_MUTATE_H
-#define LLVM_FUZZER_MUTATE_H
-
-#include "FuzzerDefs.h"
-#include "FuzzerDictionary.h"
-#include "FuzzerOptions.h"
-#include "FuzzerRandom.h"
-
-namespace fuzzer {
-
-class MutationDispatcher {
-public:
- MutationDispatcher(Random &Rand, const FuzzingOptions &Options);
- ~MutationDispatcher() {}
- /// Indicate that we are about to start a new sequence of mutations.
- void StartMutationSequence();
- /// Print the current sequence of mutations. Only prints the full sequence
- /// when Verbose is true.
- void PrintMutationSequence(bool Verbose = true);
- /// Return the current sequence of mutations.
- std::string MutationSequence();
- /// Indicate that the current sequence of mutations was successful.
- void RecordSuccessfulMutationSequence();
- /// Mutates data by invoking user-provided mutator.
- size_t Mutate_Custom(uint8_t *Data, size_t Size, size_t MaxSize);
- /// Mutates data by invoking user-provided crossover.
- size_t Mutate_CustomCrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
- /// Mutates data by shuffling bytes.
- size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);
- /// Mutates data by erasing bytes.
- size_t Mutate_EraseBytes(uint8_t *Data, size_t Size, size_t MaxSize);
- /// Mutates data by inserting a byte.
- size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize);
- /// Mutates data by inserting several repeated bytes.
- size_t Mutate_InsertRepeatedBytes(uint8_t *Data, size_t Size, size_t MaxSize);
- /// Mutates data by changing one byte.
- size_t Mutate_ChangeByte(uint8_t *Data, size_t Size, size_t MaxSize);
- /// Mutates data by changing one bit.
- size_t Mutate_ChangeBit(uint8_t *Data, size_t Size, size_t MaxSize);
- /// Mutates data by copying/inserting a part of data into a different place.
- size_t Mutate_CopyPart(uint8_t *Data, size_t Size, size_t MaxSize);
-
- /// Mutates data by adding a word from the manual dictionary.
- size_t Mutate_AddWordFromManualDictionary(uint8_t *Data, size_t Size,
- size_t MaxSize);
-
- /// Mutates data by adding a word from the TORC.
- size_t Mutate_AddWordFromTORC(uint8_t *Data, size_t Size, size_t MaxSize);
-
- /// Mutates data by adding a word from the persistent automatic dictionary.
- size_t Mutate_AddWordFromPersistentAutoDictionary(uint8_t *Data, size_t Size,
- size_t MaxSize);
-
- /// Tries to find an ASCII integer in Data, changes it to another ASCII int.
- size_t Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size, size_t MaxSize);
- /// Change a 1-, 2-, 4-, or 8-byte integer in interesting ways.
- size_t Mutate_ChangeBinaryInteger(uint8_t *Data, size_t Size, size_t MaxSize);
-
- /// CrossOver Data with CrossOverWith.
- size_t Mutate_CrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
-
- /// Applies one of the configured mutations.
- /// Returns the new size of data which could be up to MaxSize.
- size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);
-
- /// Applies one of the configured mutations to the bytes of Data
- /// that have '1' in Mask.
- /// Mask.size() should be >= Size.
- size_t MutateWithMask(uint8_t *Data, size_t Size, size_t MaxSize,
- const Vector<uint8_t> &Mask);
-
- /// Applies one of the default mutations. Provided as a service
- /// to mutation authors.
- size_t DefaultMutate(uint8_t *Data, size_t Size, size_t MaxSize);
-
- /// Creates a cross-over of two pieces of Data, returns its size.
- size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2,
- size_t Size2, uint8_t *Out, size_t MaxOutSize);
-
- void AddWordToManualDictionary(const Word &W);
-
- void PrintRecommendedDictionary();
-
- void SetCrossOverWith(const Unit *U) { CrossOverWith = U; }
-
- Random &GetRand() { return Rand; }
-
- private:
- struct Mutator {
- size_t (MutationDispatcher::*Fn)(uint8_t *Data, size_t Size, size_t Max);
- const char *Name;
- };
-
- size_t AddWordFromDictionary(Dictionary &D, uint8_t *Data, size_t Size,
- size_t MaxSize);
- size_t MutateImpl(uint8_t *Data, size_t Size, size_t MaxSize,
- Vector<Mutator> &Mutators);
-
- size_t InsertPartOf(const uint8_t *From, size_t FromSize, uint8_t *To,
- size_t ToSize, size_t MaxToSize);
- size_t CopyPartOf(const uint8_t *From, size_t FromSize, uint8_t *To,
- size_t ToSize);
- size_t ApplyDictionaryEntry(uint8_t *Data, size_t Size, size_t MaxSize,
- DictionaryEntry &DE);
-
- template <class T>
- DictionaryEntry MakeDictionaryEntryFromCMP(T Arg1, T Arg2,
- const uint8_t *Data, size_t Size);
- DictionaryEntry MakeDictionaryEntryFromCMP(const Word &Arg1, const Word &Arg2,
- const uint8_t *Data, size_t Size);
- DictionaryEntry MakeDictionaryEntryFromCMP(const void *Arg1, const void *Arg2,
- const void *Arg1Mutation,
- const void *Arg2Mutation,
- size_t ArgSize,
- const uint8_t *Data, size_t Size);
-
- Random &Rand;
- const FuzzingOptions Options;
-
- // Dictionary provided by the user via -dict=DICT_FILE.
- Dictionary ManualDictionary;
- // Persistent dictionary modified by the fuzzer, consists of
- // entries that led to successful discoveries in the past mutations.
- Dictionary PersistentAutoDictionary;
-
- Vector<DictionaryEntry *> CurrentDictionaryEntrySequence;
-
- static const size_t kCmpDictionaryEntriesDequeSize = 16;
- DictionaryEntry CmpDictionaryEntriesDeque[kCmpDictionaryEntriesDequeSize];
- size_t CmpDictionaryEntriesDequeIdx = 0;
-
- const Unit *CrossOverWith = nullptr;
- Vector<uint8_t> MutateInPlaceHere;
- Vector<uint8_t> MutateWithMaskTemp;
- // CustomCrossOver needs its own buffer as a custom implementation may call
- // LLVMFuzzerMutate, which in turn may resize MutateInPlaceHere.
- Vector<uint8_t> CustomCrossOverInPlaceHere;
-
- Vector<Mutator> Mutators;
- Vector<Mutator> DefaultMutators;
- Vector<Mutator> CurrentMutatorSequence;
-};
-
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_MUTATE_H
diff --git a/contrib/libs/libfuzzer12/FuzzerOptions.h b/contrib/libs/libfuzzer12/FuzzerOptions.h
deleted file mode 100644
index 2e8501626ba..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerOptions.h
+++ /dev/null
@@ -1,93 +0,0 @@
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// fuzzer::FuzzingOptions
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_OPTIONS_H
-#define LLVM_FUZZER_OPTIONS_H
-
-#include "FuzzerDefs.h"
-
-namespace fuzzer {
-
-struct FuzzingOptions {
- int Verbosity = 1;
- size_t MaxLen = 0;
- size_t LenControl = 1000;
- bool KeepSeed = false;
- int UnitTimeoutSec = 300;
- int TimeoutExitCode = 70;
- int OOMExitCode = 71;
- int InterruptExitCode = 72;
- int ErrorExitCode = 77;
- bool DumpInterrupted = false;
- bool IgnoreTimeouts = true;
- bool IgnoreOOMs = true;
- bool IgnoreCrashes = false;
- int MaxTotalTimeSec = 0;
- int RssLimitMb = 0;
- int MallocLimitMb = 0;
- bool DoCrossOver = true;
- bool CrossOverUniformDist = false;
- int MutateDepth = 5;
- bool ReduceDepth = false;
- bool UseCounters = false;
- bool UseMemmem = true;
- bool UseCmp = false;
- int UseValueProfile = false;
- bool Shrink = false;
- bool ReduceInputs = false;
- int ReloadIntervalSec = 1;
- bool ShuffleAtStartUp = true;
- bool PreferSmall = true;
- size_t MaxNumberOfRuns = -1L;
- int ReportSlowUnits = 10;
- bool OnlyASCII = false;
- bool Entropic = true;
- size_t EntropicFeatureFrequencyThreshold = 0xFF;
- size_t EntropicNumberOfRarestFeatures = 100;
- bool EntropicScalePerExecTime = false;
- std::string OutputCorpus;
- std::string ArtifactPrefix = "./";
- std::string ExactArtifactPath;
- std::string ExitOnSrcPos;
- std::string ExitOnItem;
- std::string FocusFunction;
- std::string DataFlowTrace;
- std::string CollectDataFlow;
- std::string FeaturesDir;
- std::string MutationGraphFile;
- std::string StopFile;
- bool SaveArtifacts = true;
- bool PrintNEW = true; // Print a status line when new units are found;
- bool PrintNewCovPcs = false;
- int PrintNewCovFuncs = 0;
- bool PrintFinalStats = false;
- bool PrintCorpusStats = false;
- bool PrintCoverage = false;
- bool PrintFullCoverage = false;
- bool DumpCoverage = false;
- bool DetectLeaks = true;
- int PurgeAllocatorIntervalSec = 1;
- int TraceMalloc = 0;
- bool HandleAbrt = false;
- bool HandleAlrm = false;
- bool HandleBus = false;
- bool HandleFpe = false;
- bool HandleIll = false;
- bool HandleInt = false;
- bool HandleSegv = false;
- bool HandleTerm = false;
- bool HandleXfsz = false;
- bool HandleUsr1 = false;
- bool HandleUsr2 = false;
- bool HandleWinExcept = false;
-};
-
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_OPTIONS_H
diff --git a/contrib/libs/libfuzzer12/FuzzerPlatform.h b/contrib/libs/libfuzzer12/FuzzerPlatform.h
deleted file mode 100644
index 1602e678950..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerPlatform.h
+++ /dev/null
@@ -1,147 +0,0 @@
-//===-- FuzzerPlatform.h --------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Common platform macros.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_PLATFORM_H
-#define LLVM_FUZZER_PLATFORM_H
-
-// Platform detection.
-#ifdef __linux__
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_FUCHSIA 0
-#define LIBFUZZER_LINUX 1
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_WINDOWS 0
-#define LIBFUZZER_EMSCRIPTEN 0
-#elif __APPLE__
-#define LIBFUZZER_APPLE 1
-#define LIBFUZZER_FUCHSIA 0
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_WINDOWS 0
-#define LIBFUZZER_EMSCRIPTEN 0
-#elif __NetBSD__
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_FUCHSIA 0
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_NETBSD 1
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_WINDOWS 0
-#define LIBFUZZER_EMSCRIPTEN 0
-#elif __FreeBSD__
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_FUCHSIA 0
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 1
-#define LIBFUZZER_WINDOWS 0
-#define LIBFUZZER_EMSCRIPTEN 0
-#elif _WIN32
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_FUCHSIA 0
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_WINDOWS 1
-#define LIBFUZZER_EMSCRIPTEN 0
-#elif __Fuchsia__
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_FUCHSIA 1
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_WINDOWS 0
-#define LIBFUZZER_EMSCRIPTEN 0
-#elif __EMSCRIPTEN__
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_FUCHSIA 0
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_WINDOWS 0
-#define LIBFUZZER_EMSCRIPTEN 1
-#else
-#error "Support for your platform has not been implemented"
-#endif
-
-#if defined(_MSC_VER) && !defined(__clang__)
-// MSVC compiler is being used.
-#define LIBFUZZER_MSVC 1
-#else
-#define LIBFUZZER_MSVC 0
-#endif
-
-#ifndef __has_attribute
-#define __has_attribute(x) 0
-#endif
-
-#define LIBFUZZER_POSIX \
- (LIBFUZZER_APPLE || LIBFUZZER_LINUX || LIBFUZZER_NETBSD || \
- LIBFUZZER_FREEBSD || LIBFUZZER_EMSCRIPTEN)
-
-#ifdef __x86_64
-#if __has_attribute(target)
-#define ATTRIBUTE_TARGET_POPCNT __attribute__((target("popcnt")))
-#else
-#define ATTRIBUTE_TARGET_POPCNT
-#endif
-#else
-#define ATTRIBUTE_TARGET_POPCNT
-#endif
-
-#ifdef __clang__ // avoid gcc warning.
-#if __has_attribute(no_sanitize)
-#define ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory")))
-#else
-#define ATTRIBUTE_NO_SANITIZE_MEMORY
-#endif
-#define ALWAYS_INLINE __attribute__((always_inline))
-#else
-#define ATTRIBUTE_NO_SANITIZE_MEMORY
-#define ALWAYS_INLINE
-#endif // __clang__
-
-#if LIBFUZZER_WINDOWS
-#define ATTRIBUTE_NO_SANITIZE_ADDRESS
-#else
-#define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
-#endif
-
-#if LIBFUZZER_WINDOWS
-#define ATTRIBUTE_ALIGNED(X) __declspec(align(X))
-#define ATTRIBUTE_INTERFACE __declspec(dllexport)
-// This is used for __sancov_lowest_stack which is needed for
-// -fsanitize-coverage=stack-depth. That feature is not yet available on
-// Windows, so make the symbol static to avoid linking errors.
-#define ATTRIBUTES_INTERFACE_TLS_INITIAL_EXEC static
-#define ATTRIBUTE_NOINLINE __declspec(noinline)
-#else
-#define ATTRIBUTE_ALIGNED(X) __attribute__((aligned(X)))
-#define ATTRIBUTE_INTERFACE __attribute__((visibility("default")))
-#define ATTRIBUTES_INTERFACE_TLS_INITIAL_EXEC \
- ATTRIBUTE_INTERFACE __attribute__((tls_model("initial-exec"))) thread_local
-
-#define ATTRIBUTE_NOINLINE __attribute__((noinline))
-#endif
-
-#if defined(__has_feature)
-#if __has_feature(address_sanitizer)
-#define ATTRIBUTE_NO_SANITIZE_ALL ATTRIBUTE_NO_SANITIZE_ADDRESS
-#elif __has_feature(memory_sanitizer)
-#define ATTRIBUTE_NO_SANITIZE_ALL ATTRIBUTE_NO_SANITIZE_MEMORY
-#else
-#define ATTRIBUTE_NO_SANITIZE_ALL
-#endif
-#else
-#define ATTRIBUTE_NO_SANITIZE_ALL
-#endif
-
-#endif // LLVM_FUZZER_PLATFORM_H
diff --git a/contrib/libs/libfuzzer12/FuzzerRandom.h b/contrib/libs/libfuzzer12/FuzzerRandom.h
deleted file mode 100644
index 659283eee20..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerRandom.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===- FuzzerRandom.h - Internal header for the Fuzzer ----------*- 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
-//
-//===----------------------------------------------------------------------===//
-// fuzzer::Random
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_RANDOM_H
-#define LLVM_FUZZER_RANDOM_H
-
-#include <random>
-
-namespace fuzzer {
-class Random : public std::minstd_rand {
- public:
- Random(unsigned int seed) : std::minstd_rand(seed) {}
- result_type operator()() { return this->std::minstd_rand::operator()(); }
- size_t Rand() { return this->operator()(); }
- size_t RandBool() { return Rand() % 2; }
- size_t SkewTowardsLast(size_t n) {
- size_t T = this->operator()(n * n);
- size_t Res = sqrt(T);
- return Res;
- }
- size_t operator()(size_t n) { return n ? Rand() % n : 0; }
- intptr_t operator()(intptr_t From, intptr_t To) {
- assert(From < To);
- intptr_t RangeSize = To - From + 1;
- return operator()(RangeSize) + From;
- }
-};
-
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_RANDOM_H
diff --git a/contrib/libs/libfuzzer12/FuzzerSHA1.cpp b/contrib/libs/libfuzzer12/FuzzerSHA1.cpp
deleted file mode 100644
index 2005dc70030..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerSHA1.cpp
+++ /dev/null
@@ -1,223 +0,0 @@
-//===- FuzzerSHA1.h - Private copy of the SHA1 implementation ---*- 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 code is taken from public domain
-// (http://oauth.googlecode.com/svn/code/c/liboauth/src/sha1.c)
-// and modified by adding anonymous namespace, adding an interface
-// function fuzzer::ComputeSHA1() and removing unnecessary code.
-//
-// lib/Fuzzer can not use SHA1 implementation from openssl because
-// openssl may not be available and because we may be fuzzing openssl itself.
-// For the same reason we do not want to depend on SHA1 from LLVM tree.
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerSHA1.h"
-#include "FuzzerDefs.h"
-#include "FuzzerPlatform.h"
-
-/* This code is public-domain - it is based on libcrypt
- * placed in the public domain by Wei Dai and other contributors.
- */
-
-#include <iomanip>
-#include <sstream>
-#include <stdint.h>
-#include <string.h>
-
-namespace { // Added for LibFuzzer
-
-#ifdef __BIG_ENDIAN__
-# define SHA_BIG_ENDIAN
-// Windows is always little endian and MSVC doesn't have <endian.h>
-#elif defined __LITTLE_ENDIAN__ || LIBFUZZER_WINDOWS
-/* override */
-#elif defined __BYTE_ORDER
-# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-# define SHA_BIG_ENDIAN
-# endif
-#else // ! defined __LITTLE_ENDIAN__
-# include <endian.h> // machine/endian.h
-# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-# define SHA_BIG_ENDIAN
-# endif
-#endif
-
-
-/* header */
-
-#define HASH_LENGTH 20
-#define BLOCK_LENGTH 64
-
-typedef struct sha1nfo {
- uint32_t buffer[BLOCK_LENGTH/4];
- uint32_t state[HASH_LENGTH/4];
- uint32_t byteCount;
- uint8_t bufferOffset;
- uint8_t keyBuffer[BLOCK_LENGTH];
- uint8_t innerHash[HASH_LENGTH];
-} sha1nfo;
-
-/* public API - prototypes - TODO: doxygen*/
-
-/**
- */
-void sha1_init(sha1nfo *s);
-/**
- */
-void sha1_writebyte(sha1nfo *s, uint8_t data);
-/**
- */
-void sha1_write(sha1nfo *s, const char *data, size_t len);
-/**
- */
-uint8_t* sha1_result(sha1nfo *s);
-
-
-/* code */
-#define SHA1_K0 0x5a827999
-#define SHA1_K20 0x6ed9eba1
-#define SHA1_K40 0x8f1bbcdc
-#define SHA1_K60 0xca62c1d6
-
-void sha1_init(sha1nfo *s) {
- s->state[0] = 0x67452301;
- s->state[1] = 0xefcdab89;
- s->state[2] = 0x98badcfe;
- s->state[3] = 0x10325476;
- s->state[4] = 0xc3d2e1f0;
- s->byteCount = 0;
- s->bufferOffset = 0;
-}
-
-uint32_t sha1_rol32(uint32_t number, uint8_t bits) {
- return ((number << bits) | (number >> (32-bits)));
-}
-
-void sha1_hashBlock(sha1nfo *s) {
- uint8_t i;
- uint32_t a,b,c,d,e,t;
-
- a=s->state[0];
- b=s->state[1];
- c=s->state[2];
- d=s->state[3];
- e=s->state[4];
- for (i=0; i<80; i++) {
- if (i>=16) {
- t = s->buffer[(i+13)&15] ^ s->buffer[(i+8)&15] ^ s->buffer[(i+2)&15] ^ s->buffer[i&15];
- s->buffer[i&15] = sha1_rol32(t,1);
- }
- if (i<20) {
- t = (d ^ (b & (c ^ d))) + SHA1_K0;
- } else if (i<40) {
- t = (b ^ c ^ d) + SHA1_K20;
- } else if (i<60) {
- t = ((b & c) | (d & (b | c))) + SHA1_K40;
- } else {
- t = (b ^ c ^ d) + SHA1_K60;
- }
- t+=sha1_rol32(a,5) + e + s->buffer[i&15];
- e=d;
- d=c;
- c=sha1_rol32(b,30);
- b=a;
- a=t;
- }
- s->state[0] += a;
- s->state[1] += b;
- s->state[2] += c;
- s->state[3] += d;
- s->state[4] += e;
-}
-
-void sha1_addUncounted(sha1nfo *s, uint8_t data) {
- uint8_t * const b = (uint8_t*) s->buffer;
-#ifdef SHA_BIG_ENDIAN
- b[s->bufferOffset] = data;
-#else
- b[s->bufferOffset ^ 3] = data;
-#endif
- s->bufferOffset++;
- if (s->bufferOffset == BLOCK_LENGTH) {
- sha1_hashBlock(s);
- s->bufferOffset = 0;
- }
-}
-
-void sha1_writebyte(sha1nfo *s, uint8_t data) {
- ++s->byteCount;
- sha1_addUncounted(s, data);
-}
-
-void sha1_write(sha1nfo *s, const char *data, size_t len) {
- for (;len--;) sha1_writebyte(s, (uint8_t) *data++);
-}
-
-void sha1_pad(sha1nfo *s) {
- // Implement SHA-1 padding (fips180-2 §5.1.1)
-
- // Pad with 0x80 followed by 0x00 until the end of the block
- sha1_addUncounted(s, 0x80);
- while (s->bufferOffset != 56) sha1_addUncounted(s, 0x00);
-
- // Append length in the last 8 bytes
- sha1_addUncounted(s, 0); // We're only using 32 bit lengths
- sha1_addUncounted(s, 0); // But SHA-1 supports 64 bit lengths
- sha1_addUncounted(s, 0); // So zero pad the top bits
- sha1_addUncounted(s, s->byteCount >> 29); // Shifting to multiply by 8
- sha1_addUncounted(s, s->byteCount >> 21); // as SHA-1 supports bitstreams as well as
- sha1_addUncounted(s, s->byteCount >> 13); // byte.
- sha1_addUncounted(s, s->byteCount >> 5);
- sha1_addUncounted(s, s->byteCount << 3);
-}
-
-uint8_t* sha1_result(sha1nfo *s) {
- // Pad to complete the last block
- sha1_pad(s);
-
-#ifndef SHA_BIG_ENDIAN
- // Swap byte order back
- int i;
- for (i=0; i<5; i++) {
- s->state[i]=
- (((s->state[i])<<24)& 0xff000000)
- | (((s->state[i])<<8) & 0x00ff0000)
- | (((s->state[i])>>8) & 0x0000ff00)
- | (((s->state[i])>>24)& 0x000000ff);
- }
-#endif
-
- // Return pointer to hash (20 characters)
- return (uint8_t*) s->state;
-}
-
-} // namespace; Added for LibFuzzer
-
-namespace fuzzer {
-
-// The rest is added for LibFuzzer
-void ComputeSHA1(const uint8_t *Data, size_t Len, uint8_t *Out) {
- sha1nfo s;
- sha1_init(&s);
- sha1_write(&s, (const char*)Data, Len);
- memcpy(Out, sha1_result(&s), HASH_LENGTH);
-}
-
-std::string Sha1ToString(const uint8_t Sha1[kSHA1NumBytes]) {
- std::stringstream SS;
- for (int i = 0; i < kSHA1NumBytes; i++)
- SS << std::hex << std::setfill('0') << std::setw(2) << (unsigned)Sha1[i];
- return SS.str();
-}
-
-std::string Hash(const Unit &U) {
- uint8_t Hash[kSHA1NumBytes];
- ComputeSHA1(U.data(), U.size(), Hash);
- return Sha1ToString(Hash);
-}
-
-}
diff --git a/contrib/libs/libfuzzer12/FuzzerSHA1.h b/contrib/libs/libfuzzer12/FuzzerSHA1.h
deleted file mode 100644
index 05cbacda87d..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerSHA1.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//===- FuzzerSHA1.h - Internal header for the SHA1 utils --------*- 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
-//
-//===----------------------------------------------------------------------===//
-// SHA1 utils.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_SHA1_H
-#define LLVM_FUZZER_SHA1_H
-
-#include "FuzzerDefs.h"
-#include <cstddef>
-#include <stdint.h>
-
-namespace fuzzer {
-
-// Private copy of SHA1 implementation.
-static const int kSHA1NumBytes = 20;
-
-// Computes SHA1 hash of 'Len' bytes in 'Data', writes kSHA1NumBytes to 'Out'.
-void ComputeSHA1(const uint8_t *Data, size_t Len, uint8_t *Out);
-
-std::string Sha1ToString(const uint8_t Sha1[kSHA1NumBytes]);
-
-std::string Hash(const Unit &U);
-
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_SHA1_H
diff --git a/contrib/libs/libfuzzer12/FuzzerTracePC.cpp b/contrib/libs/libfuzzer12/FuzzerTracePC.cpp
deleted file mode 100644
index 91e94d82400..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerTracePC.cpp
+++ /dev/null
@@ -1,673 +0,0 @@
-//===- FuzzerTracePC.cpp - PC tracing--------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Trace PCs.
-// This module implements __sanitizer_cov_trace_pc_guard[_init],
-// the callback required for -fsanitize-coverage=trace-pc-guard instrumentation.
-//
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerTracePC.h"
-#include "FuzzerBuiltins.h"
-#include "FuzzerBuiltinsMsvc.h"
-#include "FuzzerCorpus.h"
-#include "FuzzerDefs.h"
-#include "FuzzerDictionary.h"
-#include "FuzzerExtFunctions.h"
-#include "FuzzerIO.h"
-#include "FuzzerPlatform.h"
-#include "FuzzerUtil.h"
-#include "FuzzerValueBitMap.h"
-#include <set>
-
-// Used by -fsanitize-coverage=stack-depth to track stack depth
-ATTRIBUTES_INTERFACE_TLS_INITIAL_EXEC uintptr_t __sancov_lowest_stack;
-
-namespace fuzzer {
-
-TracePC TPC;
-
-size_t TracePC::GetTotalPCCoverage() {
- return ObservedPCs.size();
-}
-
-
-void TracePC::HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop) {
- if (Start == Stop) return;
- if (NumModules &&
- Modules[NumModules - 1].Start() == Start)
- return;
- assert(NumModules <
- sizeof(Modules) / sizeof(Modules[0]));
- auto &M = Modules[NumModules++];
- uint8_t *AlignedStart = RoundUpByPage(Start);
- uint8_t *AlignedStop = RoundDownByPage(Stop);
- size_t NumFullPages = AlignedStop > AlignedStart ?
- (AlignedStop - AlignedStart) / PageSize() : 0;
- bool NeedFirst = Start < AlignedStart || !NumFullPages;
- bool NeedLast = Stop > AlignedStop && AlignedStop >= AlignedStart;
- M.NumRegions = NumFullPages + NeedFirst + NeedLast;;
- assert(M.NumRegions > 0);
- M.Regions = new Module::Region[M.NumRegions];
- assert(M.Regions);
- size_t R = 0;
- if (NeedFirst)
- M.Regions[R++] = {Start, std::min(Stop, AlignedStart), true, false};
- for (uint8_t *P = AlignedStart; P < AlignedStop; P += PageSize())
- M.Regions[R++] = {P, P + PageSize(), true, true};
- if (NeedLast)
- M.Regions[R++] = {AlignedStop, Stop, true, false};
- assert(R == M.NumRegions);
- assert(M.Size() == (size_t)(Stop - Start));
- assert(M.Stop() == Stop);
- assert(M.Start() == Start);
- NumInline8bitCounters += M.Size();
-}
-
-void TracePC::HandlePCsInit(const uintptr_t *Start, const uintptr_t *Stop) {
- const PCTableEntry *B = reinterpret_cast<const PCTableEntry *>(Start);
- const PCTableEntry *E = reinterpret_cast<const PCTableEntry *>(Stop);
- if (NumPCTables && ModulePCTable[NumPCTables - 1].Start == B) return;
- assert(NumPCTables < sizeof(ModulePCTable) / sizeof(ModulePCTable[0]));
- ModulePCTable[NumPCTables++] = {B, E};
- NumPCsInPCTables += E - B;
-}
-
-void TracePC::PrintModuleInfo() {
- if (NumModules) {
- Printf("INFO: Loaded %zd modules (%zd inline 8-bit counters): ",
- NumModules, NumInline8bitCounters);
- for (size_t i = 0; i < NumModules; i++)
- Printf("%zd [%p, %p), ", Modules[i].Size(), Modules[i].Start(),
- Modules[i].Stop());
- Printf("\n");
- }
- if (NumPCTables) {
- Printf("INFO: Loaded %zd PC tables (%zd PCs): ", NumPCTables,
- NumPCsInPCTables);
- for (size_t i = 0; i < NumPCTables; i++) {
- Printf("%zd [%p,%p), ", ModulePCTable[i].Stop - ModulePCTable[i].Start,
- ModulePCTable[i].Start, ModulePCTable[i].Stop);
- }
- Printf("\n");
-
- if (NumInline8bitCounters && NumInline8bitCounters != NumPCsInPCTables) {
- Printf("ERROR: The size of coverage PC tables does not match the\n"
- "number of instrumented PCs. This might be a compiler bug,\n"
- "please contact the libFuzzer developers.\n"
- "Also check https://bugs.llvm.org/show_bug.cgi?id=34636\n"
- "for possible workarounds (tl;dr: don't use the old GNU ld)\n");
- _Exit(1);
- }
- }
- if (size_t NumExtraCounters = ExtraCountersEnd() - ExtraCountersBegin())
- Printf("INFO: %zd Extra Counters\n", NumExtraCounters);
-}
-
-ATTRIBUTE_NO_SANITIZE_ALL
-void TracePC::HandleCallerCallee(uintptr_t Caller, uintptr_t Callee) {
- const uintptr_t kBits = 12;
- const uintptr_t kMask = (1 << kBits) - 1;
- uintptr_t Idx = (Caller & kMask) | ((Callee & kMask) << kBits);
- ValueProfileMap.AddValueModPrime(Idx);
-}
-
-/// \return the address of the previous instruction.
-/// Note: the logic is copied from `sanitizer_common/sanitizer_stacktrace.h`
-inline ALWAYS_INLINE uintptr_t GetPreviousInstructionPc(uintptr_t PC) {
-#if defined(__arm__)
- // T32 (Thumb) branch instructions might be 16 or 32 bit long,
- // so we return (pc-2) in that case in order to be safe.
- // For A32 mode we return (pc-4) because all instructions are 32 bit long.
- return (PC - 3) & (~1);
-#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__aarch64__)
- // PCs are always 4 byte aligned.
- return PC - 4;
-#elif defined(__sparc__) || defined(__mips__)
- return PC - 8;
-#else
- return PC - 1;
-#endif
-}
-
-/// \return the address of the next instruction.
-/// Note: the logic is copied from `sanitizer_common/sanitizer_stacktrace.cpp`
-ALWAYS_INLINE uintptr_t TracePC::GetNextInstructionPc(uintptr_t PC) {
-#if defined(__mips__)
- return PC + 8;
-#elif defined(__powerpc__) || defined(__sparc__) || defined(__arm__) || \
- defined(__aarch64__)
- return PC + 4;
-#else
- return PC + 1;
-#endif
-}
-
-void TracePC::UpdateObservedPCs() {
- Vector<uintptr_t> CoveredFuncs;
- auto ObservePC = [&](const PCTableEntry *TE) {
- if (ObservedPCs.insert(TE).second && DoPrintNewPCs) {
- PrintPC("\tNEW_PC: %p %F %L", "\tNEW_PC: %p",
- GetNextInstructionPc(TE->PC));
- Printf("\n");
- }
- };
-
- auto Observe = [&](const PCTableEntry *TE) {
- if (PcIsFuncEntry(TE))
- if (++ObservedFuncs[TE->PC] == 1 && NumPrintNewFuncs)
- CoveredFuncs.push_back(TE->PC);
- ObservePC(TE);
- };
-
- if (NumPCsInPCTables) {
- if (NumInline8bitCounters == NumPCsInPCTables) {
- for (size_t i = 0; i < NumModules; i++) {
- auto &M = Modules[i];
- assert(M.Size() ==
- (size_t)(ModulePCTable[i].Stop - ModulePCTable[i].Start));
- for (size_t r = 0; r < M.NumRegions; r++) {
- auto &R = M.Regions[r];
- if (!R.Enabled) continue;
- for (uint8_t *P = R.Start; P < R.Stop; P++)
- if (*P)
- Observe(&ModulePCTable[i].Start[M.Idx(P)]);
- }
- }
- }
- }
-
- for (size_t i = 0, N = Min(CoveredFuncs.size(), NumPrintNewFuncs); i < N;
- i++) {
- Printf("\tNEW_FUNC[%zd/%zd]: ", i + 1, CoveredFuncs.size());
- PrintPC("%p %F %L", "%p", GetNextInstructionPc(CoveredFuncs[i]));
- Printf("\n");
- }
-}
-
-uintptr_t TracePC::PCTableEntryIdx(const PCTableEntry *TE) {
- size_t TotalTEs = 0;
- for (size_t i = 0; i < NumPCTables; i++) {
- auto &M = ModulePCTable[i];
- if (TE >= M.Start && TE < M.Stop)
- return TotalTEs + TE - M.Start;
- TotalTEs += M.Stop - M.Start;
- }
- assert(0);
- return 0;
-}
-
-const TracePC::PCTableEntry *TracePC::PCTableEntryByIdx(uintptr_t Idx) {
- for (size_t i = 0; i < NumPCTables; i++) {
- auto &M = ModulePCTable[i];
- size_t Size = M.Stop - M.Start;
- if (Idx < Size) return &M.Start[Idx];
- Idx -= Size;
- }
- return nullptr;
-}
-
-static std::string GetModuleName(uintptr_t PC) {
- char ModulePathRaw[4096] = ""; // What's PATH_MAX in portable C++?
- void *OffsetRaw = nullptr;
- if (!EF->__sanitizer_get_module_and_offset_for_pc(
- reinterpret_cast<void *>(PC), ModulePathRaw,
- sizeof(ModulePathRaw), &OffsetRaw))
- return "";
- return ModulePathRaw;
-}
-
-template<class CallBack>
-void TracePC::IterateCoveredFunctions(CallBack CB) {
- for (size_t i = 0; i < NumPCTables; i++) {
- auto &M = ModulePCTable[i];
- assert(M.Start < M.Stop);
- auto ModuleName = GetModuleName(M.Start->PC);
- for (auto NextFE = M.Start; NextFE < M.Stop; ) {
- auto FE = NextFE;
- assert(PcIsFuncEntry(FE) && "Not a function entry point");
- do {
- NextFE++;
- } while (NextFE < M.Stop && !(PcIsFuncEntry(NextFE)));
- CB(FE, NextFE, ObservedFuncs[FE->PC]);
- }
- }
-}
-
-void TracePC::SetFocusFunction(const std::string &FuncName) {
- // This function should be called once.
- assert(!FocusFunctionCounterPtr);
- // "auto" is not a valid function name. If this function is called with "auto"
- // that means the auto focus functionality failed.
- if (FuncName.empty() || FuncName == "auto")
- return;
- for (size_t M = 0; M < NumModules; M++) {
- auto &PCTE = ModulePCTable[M];
- size_t N = PCTE.Stop - PCTE.Start;
- for (size_t I = 0; I < N; I++) {
- if (!(PcIsFuncEntry(&PCTE.Start[I]))) continue; // not a function entry.
- auto Name = DescribePC("%F", GetNextInstructionPc(PCTE.Start[I].PC));
- if (Name[0] == 'i' && Name[1] == 'n' && Name[2] == ' ')
- Name = Name.substr(3, std::string::npos);
- if (FuncName != Name) continue;
- Printf("INFO: Focus function is set to '%s'\n", Name.c_str());
- FocusFunctionCounterPtr = Modules[M].Start() + I;
- return;
- }
- }
-
- Printf("ERROR: Failed to set focus function. Make sure the function name is "
- "valid (%s) and symbolization is enabled.\n", FuncName.c_str());
- exit(1);
-}
-
-bool TracePC::ObservedFocusFunction() {
- return FocusFunctionCounterPtr && *FocusFunctionCounterPtr;
-}
-
-void TracePC::PrintCoverage(bool PrintAllCounters) {
- if (!EF->__sanitizer_symbolize_pc ||
- !EF->__sanitizer_get_module_and_offset_for_pc) {
- Printf("INFO: __sanitizer_symbolize_pc or "
- "__sanitizer_get_module_and_offset_for_pc is not available,"
- " not printing coverage\n");
- return;
- }
- Printf(PrintAllCounters ? "FULL COVERAGE:\n" : "COVERAGE:\n");
- auto CoveredFunctionCallback = [&](const PCTableEntry *First,
- const PCTableEntry *Last,
- uintptr_t Counter) {
- assert(First < Last);
- auto VisualizePC = GetNextInstructionPc(First->PC);
- std::string FileStr = DescribePC("%s", VisualizePC);
- if (!IsInterestingCoverageFile(FileStr))
- return;
- std::string FunctionStr = DescribePC("%F", VisualizePC);
- if (FunctionStr.find("in ") == 0)
- FunctionStr = FunctionStr.substr(3);
- std::string LineStr = DescribePC("%l", VisualizePC);
- size_t NumEdges = Last - First;
- Vector<uintptr_t> UncoveredPCs;
- Vector<uintptr_t> CoveredPCs;
- for (auto TE = First; TE < Last; TE++)
- if (!ObservedPCs.count(TE))
- UncoveredPCs.push_back(TE->PC);
- else
- CoveredPCs.push_back(TE->PC);
-
- if (PrintAllCounters) {
- Printf("U");
- for (auto PC : UncoveredPCs)
- Printf(DescribePC(" %l", GetNextInstructionPc(PC)).c_str());
- Printf("\n");
-
- Printf("C");
- for (auto PC : CoveredPCs)
- Printf(DescribePC(" %l", GetNextInstructionPc(PC)).c_str());
- Printf("\n");
- } else {
- Printf("%sCOVERED_FUNC: hits: %zd", Counter ? "" : "UN", Counter);
- Printf(" edges: %zd/%zd", NumEdges - UncoveredPCs.size(), NumEdges);
- Printf(" %s %s:%s\n", FunctionStr.c_str(), FileStr.c_str(),
- LineStr.c_str());
- if (Counter)
- for (auto PC : UncoveredPCs)
- Printf(" UNCOVERED_PC: %s\n",
- DescribePC("%s:%l", GetNextInstructionPc(PC)).c_str());
- }
- };
-
- IterateCoveredFunctions(CoveredFunctionCallback);
-}
-
-// Value profile.
-// We keep track of various values that affect control flow.
-// These values are inserted into a bit-set-based hash map.
-// Every new bit in the map is treated as a new coverage.
-//
-// For memcmp/strcmp/etc the interesting value is the length of the common
-// prefix of the parameters.
-// For cmp instructions the interesting value is a XOR of the parameters.
-// The interesting value is mixed up with the PC and is then added to the map.
-
-ATTRIBUTE_NO_SANITIZE_ALL
-void TracePC::AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2,
- size_t n, bool StopAtZero) {
- if (!n) return;
- size_t Len = std::min(n, Word::GetMaxSize());
- const uint8_t *A1 = reinterpret_cast<const uint8_t *>(s1);
- const uint8_t *A2 = reinterpret_cast<const uint8_t *>(s2);
- uint8_t B1[Word::kMaxSize];
- uint8_t B2[Word::kMaxSize];
- // Copy the data into locals in this non-msan-instrumented function
- // to avoid msan complaining further.
- size_t Hash = 0; // Compute some simple hash of both strings.
- for (size_t i = 0; i < Len; i++) {
- B1[i] = A1[i];
- B2[i] = A2[i];
- size_t T = B1[i];
- Hash ^= (T << 8) | B2[i];
- }
- size_t I = 0;
- uint8_t HammingDistance = 0;
- for (; I < Len; I++) {
- if (B1[I] != B2[I] || (StopAtZero && B1[I] == 0)) {
- HammingDistance = Popcountll(B1[I] ^ B2[I]);
- break;
- }
- }
- size_t PC = reinterpret_cast<size_t>(caller_pc);
- size_t Idx = (PC & 4095) | (I << 12);
- Idx += HammingDistance;
- ValueProfileMap.AddValue(Idx);
- TORCW.Insert(Idx ^ Hash, Word(B1, Len), Word(B2, Len));
-}
-
-template <class T>
-ATTRIBUTE_TARGET_POPCNT ALWAYS_INLINE
-ATTRIBUTE_NO_SANITIZE_ALL
-void TracePC::HandleCmp(uintptr_t PC, T Arg1, T Arg2) {
- uint64_t ArgXor = Arg1 ^ Arg2;
- if (sizeof(T) == 4)
- TORC4.Insert(ArgXor, Arg1, Arg2);
- else if (sizeof(T) == 8)
- TORC8.Insert(ArgXor, Arg1, Arg2);
- uint64_t HammingDistance = Popcountll(ArgXor); // [0,64]
- uint64_t AbsoluteDistance = (Arg1 == Arg2 ? 0 : Clzll(Arg1 - Arg2) + 1);
- ValueProfileMap.AddValue(PC * 128 + HammingDistance);
- ValueProfileMap.AddValue(PC * 128 + 64 + AbsoluteDistance);
-}
-
-static size_t InternalStrnlen(const char *S, size_t MaxLen) {
- size_t Len = 0;
- for (; Len < MaxLen && S[Len]; Len++) {}
- return Len;
-}
-
-// Finds min of (strlen(S1), strlen(S2)).
-// Needed bacause one of these strings may actually be non-zero terminated.
-static size_t InternalStrnlen2(const char *S1, const char *S2) {
- size_t Len = 0;
- for (; S1[Len] && S2[Len]; Len++) {}
- return Len;
-}
-
-void TracePC::ClearInlineCounters() {
- IterateCounterRegions([](const Module::Region &R){
- if (R.Enabled)
- memset(R.Start, 0, R.Stop - R.Start);
- });
-}
-
-ATTRIBUTE_NO_SANITIZE_ALL
-void TracePC::RecordInitialStack() {
- int stack;
- __sancov_lowest_stack = InitialStack = reinterpret_cast<uintptr_t>(&stack);
-}
-
-uintptr_t TracePC::GetMaxStackOffset() const {
- return InitialStack - __sancov_lowest_stack; // Stack grows down
-}
-
-void WarnAboutDeprecatedInstrumentation(const char *flag) {
- // Use RawPrint because Printf cannot be used on Windows before OutputFile is
- // initialized.
- RawPrint(flag);
- RawPrint(
- " is no longer supported by libFuzzer.\n"
- "Please either migrate to a compiler that supports -fsanitize=fuzzer\n"
- "or use an older version of libFuzzer\n");
- exit(1);
-}
-
-} // namespace fuzzer
-
-extern "C" {
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-void __sanitizer_cov_trace_pc_guard(uint32_t *Guard) {
- fuzzer::WarnAboutDeprecatedInstrumentation(
- "-fsanitize-coverage=trace-pc-guard");
-}
-
-// Best-effort support for -fsanitize-coverage=trace-pc, which is available
-// in both Clang and GCC.
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-void __sanitizer_cov_trace_pc() {
- fuzzer::WarnAboutDeprecatedInstrumentation("-fsanitize-coverage=trace-pc");
-}
-
-ATTRIBUTE_INTERFACE
-void __sanitizer_cov_trace_pc_guard_init(uint32_t *Start, uint32_t *Stop) {
- fuzzer::WarnAboutDeprecatedInstrumentation(
- "-fsanitize-coverage=trace-pc-guard");
-}
-
-ATTRIBUTE_INTERFACE
-void __sanitizer_cov_8bit_counters_init(uint8_t *Start, uint8_t *Stop) {
- fuzzer::TPC.HandleInline8bitCountersInit(Start, Stop);
-}
-
-ATTRIBUTE_INTERFACE
-void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
- const uintptr_t *pcs_end) {
- fuzzer::TPC.HandlePCsInit(pcs_beg, pcs_end);
-}
-
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-void __sanitizer_cov_trace_pc_indir(uintptr_t Callee) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
- fuzzer::TPC.HandleCallerCallee(PC, Callee);
-}
-
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-ATTRIBUTE_TARGET_POPCNT
-void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
- fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
-}
-
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-ATTRIBUTE_TARGET_POPCNT
-// Now the __sanitizer_cov_trace_const_cmp[1248] callbacks just mimic
-// the behaviour of __sanitizer_cov_trace_cmp[1248] ones. This, however,
-// should be changed later to make full use of instrumentation.
-void __sanitizer_cov_trace_const_cmp8(uint64_t Arg1, uint64_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
- fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
-}
-
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-ATTRIBUTE_TARGET_POPCNT
-void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
- fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
-}
-
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-ATTRIBUTE_TARGET_POPCNT
-void __sanitizer_cov_trace_const_cmp4(uint32_t Arg1, uint32_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
- fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
-}
-
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-ATTRIBUTE_TARGET_POPCNT
-void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
- fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
-}
-
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-ATTRIBUTE_TARGET_POPCNT
-void __sanitizer_cov_trace_const_cmp2(uint16_t Arg1, uint16_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
- fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
-}
-
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-ATTRIBUTE_TARGET_POPCNT
-void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
- fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
-}
-
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-ATTRIBUTE_TARGET_POPCNT
-void __sanitizer_cov_trace_const_cmp1(uint8_t Arg1, uint8_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
- fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
-}
-
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-ATTRIBUTE_TARGET_POPCNT
-void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t *Cases) {
- uint64_t N = Cases[0];
- uint64_t ValSizeInBits = Cases[1];
- uint64_t *Vals = Cases + 2;
- // Skip the most common and the most boring case: all switch values are small.
- // We may want to skip this at compile-time, but it will make the
- // instrumentation less general.
- if (Vals[N - 1] < 256)
- return;
- // Also skip small inputs values, they won't give good signal.
- if (Val < 256)
- return;
- uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
- size_t i;
- uint64_t Smaller = 0;
- uint64_t Larger = ~(uint64_t)0;
- // Find two switch values such that Smaller < Val < Larger.
- // Use 0 and 0xfff..f as the defaults.
- for (i = 0; i < N; i++) {
- if (Val < Vals[i]) {
- Larger = Vals[i];
- break;
- }
- if (Val > Vals[i]) Smaller = Vals[i];
- }
-
- // Apply HandleCmp to {Val,Smaller} and {Val, Larger},
- // use i as the PC modifier for HandleCmp.
- if (ValSizeInBits == 16) {
- fuzzer::TPC.HandleCmp(PC + 2 * i, static_cast<uint16_t>(Val),
- (uint16_t)(Smaller));
- fuzzer::TPC.HandleCmp(PC + 2 * i + 1, static_cast<uint16_t>(Val),
- (uint16_t)(Larger));
- } else if (ValSizeInBits == 32) {
- fuzzer::TPC.HandleCmp(PC + 2 * i, static_cast<uint32_t>(Val),
- (uint32_t)(Smaller));
- fuzzer::TPC.HandleCmp(PC + 2 * i + 1, static_cast<uint32_t>(Val),
- (uint32_t)(Larger));
- } else {
- fuzzer::TPC.HandleCmp(PC + 2*i, Val, Smaller);
- fuzzer::TPC.HandleCmp(PC + 2*i + 1, Val, Larger);
- }
-}
-
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-ATTRIBUTE_TARGET_POPCNT
-void __sanitizer_cov_trace_div4(uint32_t Val) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
- fuzzer::TPC.HandleCmp(PC, Val, (uint32_t)0);
-}
-
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-ATTRIBUTE_TARGET_POPCNT
-void __sanitizer_cov_trace_div8(uint64_t Val) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
- fuzzer::TPC.HandleCmp(PC, Val, (uint64_t)0);
-}
-
-ATTRIBUTE_INTERFACE
-ATTRIBUTE_NO_SANITIZE_ALL
-ATTRIBUTE_TARGET_POPCNT
-void __sanitizer_cov_trace_gep(uintptr_t Idx) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
- fuzzer::TPC.HandleCmp(PC, Idx, (uintptr_t)0);
-}
-
-ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
-void __sanitizer_weak_hook_memcmp(void *caller_pc, const void *s1,
- const void *s2, size_t n, int result) {
- if (!fuzzer::RunningUserCallback) return;
- if (result == 0) return; // No reason to mutate.
- if (n <= 1) return; // Not interesting.
- fuzzer::TPC.AddValueForMemcmp(caller_pc, s1, s2, n, /*StopAtZero*/false);
-}
-
-ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
-void __sanitizer_weak_hook_strncmp(void *caller_pc, const char *s1,
- const char *s2, size_t n, int result) {
- if (!fuzzer::RunningUserCallback) return;
- if (result == 0) return; // No reason to mutate.
- size_t Len1 = fuzzer::InternalStrnlen(s1, n);
- size_t Len2 = fuzzer::InternalStrnlen(s2, n);
- n = std::min(n, Len1);
- n = std::min(n, Len2);
- if (n <= 1) return; // Not interesting.
- fuzzer::TPC.AddValueForMemcmp(caller_pc, s1, s2, n, /*StopAtZero*/true);
-}
-
-ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
-void __sanitizer_weak_hook_strcmp(void *caller_pc, const char *s1,
- const char *s2, int result) {
- if (!fuzzer::RunningUserCallback) return;
- if (result == 0) return; // No reason to mutate.
- size_t N = fuzzer::InternalStrnlen2(s1, s2);
- if (N <= 1) return; // Not interesting.
- fuzzer::TPC.AddValueForMemcmp(caller_pc, s1, s2, N, /*StopAtZero*/true);
-}
-
-ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
-void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
- const char *s2, size_t n, int result) {
- if (!fuzzer::RunningUserCallback) return;
- return __sanitizer_weak_hook_strncmp(called_pc, s1, s2, n, result);
-}
-
-ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
-void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
- const char *s2, int result) {
- if (!fuzzer::RunningUserCallback) return;
- return __sanitizer_weak_hook_strcmp(called_pc, s1, s2, result);
-}
-
-ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
-void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
- const char *s2, char *result) {
- if (!fuzzer::RunningUserCallback) return;
- fuzzer::TPC.MMT.Add(reinterpret_cast<const uint8_t *>(s2), strlen(s2));
-}
-
-ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
-void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
- const char *s2, char *result) {
- if (!fuzzer::RunningUserCallback) return;
- fuzzer::TPC.MMT.Add(reinterpret_cast<const uint8_t *>(s2), strlen(s2));
-}
-
-ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
-void __sanitizer_weak_hook_memmem(void *called_pc, const void *s1, size_t len1,
- const void *s2, size_t len2, void *result) {
- if (!fuzzer::RunningUserCallback) return;
- fuzzer::TPC.MMT.Add(reinterpret_cast<const uint8_t *>(s2), len2);
-}
-} // extern "C"
diff --git a/contrib/libs/libfuzzer12/FuzzerTracePC.h b/contrib/libs/libfuzzer12/FuzzerTracePC.h
deleted file mode 100644
index 00909230731..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerTracePC.h
+++ /dev/null
@@ -1,291 +0,0 @@
-//===- FuzzerTracePC.h - Internal header for the Fuzzer ---------*- 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
-//
-//===----------------------------------------------------------------------===//
-// fuzzer::TracePC
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_TRACE_PC
-#define LLVM_FUZZER_TRACE_PC
-
-#include "FuzzerDefs.h"
-#include "FuzzerDictionary.h"
-#include "FuzzerValueBitMap.h"
-
-#include <set>
-#include <unordered_map>
-
-namespace fuzzer {
-
-// TableOfRecentCompares (TORC) remembers the most recently performed
-// comparisons of type T.
-// We record the arguments of CMP instructions in this table unconditionally
-// because it seems cheaper this way than to compute some expensive
-// conditions inside __sanitizer_cov_trace_cmp*.
-// After the unit has been executed we may decide to use the contents of
-// this table to populate a Dictionary.
-template<class T, size_t kSizeT>
-struct TableOfRecentCompares {
- static const size_t kSize = kSizeT;
- struct Pair {
- T A, B;
- };
- ATTRIBUTE_NO_SANITIZE_ALL
- void Insert(size_t Idx, const T &Arg1, const T &Arg2) {
- Idx = Idx % kSize;
- Table[Idx].A = Arg1;
- Table[Idx].B = Arg2;
- }
-
- Pair Get(size_t I) { return Table[I % kSize]; }
-
- Pair Table[kSize];
-};
-
-template <size_t kSizeT>
-struct MemMemTable {
- static const size_t kSize = kSizeT;
- Word MemMemWords[kSize];
- Word EmptyWord;
-
- void Add(const uint8_t *Data, size_t Size) {
- if (Size <= 2) return;
- Size = std::min(Size, Word::GetMaxSize());
- size_t Idx = SimpleFastHash(Data, Size) % kSize;
- MemMemWords[Idx].Set(Data, Size);
- }
- const Word &Get(size_t Idx) {
- for (size_t i = 0; i < kSize; i++) {
- const Word &W = MemMemWords[(Idx + i) % kSize];
- if (W.size()) return W;
- }
- EmptyWord.Set(nullptr, 0);
- return EmptyWord;
- }
-};
-
-class TracePC {
- public:
- void HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop);
- void HandlePCsInit(const uintptr_t *Start, const uintptr_t *Stop);
- void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee);
- template <class T> void HandleCmp(uintptr_t PC, T Arg1, T Arg2);
- size_t GetTotalPCCoverage();
- void SetUseCounters(bool UC) { UseCounters = UC; }
- void SetUseValueProfileMask(uint32_t VPMask) { UseValueProfileMask = VPMask; }
- void SetPrintNewPCs(bool P) { DoPrintNewPCs = P; }
- void SetPrintNewFuncs(size_t P) { NumPrintNewFuncs = P; }
- void UpdateObservedPCs();
- template <class Callback> void CollectFeatures(Callback CB) const;
-
- void ResetMaps() {
- ValueProfileMap.Reset();
- ClearExtraCounters();
- ClearInlineCounters();
- }
-
- void ClearInlineCounters();
-
- void UpdateFeatureSet(size_t CurrentElementIdx, size_t CurrentElementSize);
- void PrintFeatureSet();
-
- void PrintModuleInfo();
-
- void PrintCoverage(bool PrintAllCounters);
-
- template<class CallBack>
- void IterateCoveredFunctions(CallBack CB);
-
- void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2,
- size_t n, bool StopAtZero);
-
- TableOfRecentCompares<uint32_t, 32> TORC4;
- TableOfRecentCompares<uint64_t, 32> TORC8;
- TableOfRecentCompares<Word, 32> TORCW;
- MemMemTable<1024> MMT;
-
- void RecordInitialStack();
- uintptr_t GetMaxStackOffset() const;
-
- template<class CallBack>
- void ForEachObservedPC(CallBack CB) {
- for (auto PC : ObservedPCs)
- CB(PC);
- }
-
- void SetFocusFunction(const std::string &FuncName);
- bool ObservedFocusFunction();
-
- struct PCTableEntry {
- uintptr_t PC, PCFlags;
- };
-
- uintptr_t PCTableEntryIdx(const PCTableEntry *TE);
- const PCTableEntry *PCTableEntryByIdx(uintptr_t Idx);
- static uintptr_t GetNextInstructionPc(uintptr_t PC);
- bool PcIsFuncEntry(const PCTableEntry *TE) { return TE->PCFlags & 1; }
-
-private:
- bool UseCounters = false;
- uint32_t UseValueProfileMask = false;
- bool DoPrintNewPCs = false;
- size_t NumPrintNewFuncs = 0;
-
- // Module represents the array of 8-bit counters split into regions
- // such that every region, except maybe the first and the last one, is one
- // full page.
- struct Module {
- struct Region {
- uint8_t *Start, *Stop;
- bool Enabled;
- bool OneFullPage;
- };
- Region *Regions;
- size_t NumRegions;
- uint8_t *Start() { return Regions[0].Start; }
- uint8_t *Stop() { return Regions[NumRegions - 1].Stop; }
- size_t Size() { return Stop() - Start(); }
- size_t Idx(uint8_t *P) {
- assert(P >= Start() && P < Stop());
- return P - Start();
- }
- };
-
- Module Modules[4096];
- size_t NumModules; // linker-initialized.
- size_t NumInline8bitCounters;
-
- template <class Callback>
- void IterateCounterRegions(Callback CB) {
- for (size_t m = 0; m < NumModules; m++)
- for (size_t r = 0; r < Modules[m].NumRegions; r++)
- CB(Modules[m].Regions[r]);
- }
-
- struct { const PCTableEntry *Start, *Stop; } ModulePCTable[4096];
- size_t NumPCTables;
- size_t NumPCsInPCTables;
-
- Set<const PCTableEntry*> ObservedPCs;
- std::unordered_map<uintptr_t, uintptr_t> ObservedFuncs; // PC => Counter.
-
- uint8_t *FocusFunctionCounterPtr = nullptr;
-
- ValueBitMap ValueProfileMap;
- uintptr_t InitialStack;
-};
-
-template <class Callback>
-// void Callback(size_t FirstFeature, size_t Idx, uint8_t Value);
-ATTRIBUTE_NO_SANITIZE_ALL
-size_t ForEachNonZeroByte(const uint8_t *Begin, const uint8_t *End,
- size_t FirstFeature, Callback Handle8bitCounter) {
- typedef uintptr_t LargeType;
- const size_t Step = sizeof(LargeType) / sizeof(uint8_t);
- const size_t StepMask = Step - 1;
- auto P = Begin;
- // Iterate by 1 byte until either the alignment boundary or the end.
- for (; reinterpret_cast<uintptr_t>(P) & StepMask && P < End; P++)
- if (uint8_t V = *P)
- Handle8bitCounter(FirstFeature, P - Begin, V);
-
- // Iterate by Step bytes at a time.
- for (; P < End; P += Step)
- if (LargeType Bundle = *reinterpret_cast<const LargeType *>(P)) {
- Bundle = HostToLE(Bundle);
- for (size_t I = 0; I < Step; I++, Bundle >>= 8)
- if (uint8_t V = Bundle & 0xff)
- Handle8bitCounter(FirstFeature, P - Begin + I, V);
- }
-
- // Iterate by 1 byte until the end.
- for (; P < End; P++)
- if (uint8_t V = *P)
- Handle8bitCounter(FirstFeature, P - Begin, V);
- return End - Begin;
-}
-
-// Given a non-zero Counter returns a number in the range [0,7].
-template<class T>
-unsigned CounterToFeature(T Counter) {
- // Returns a feature number by placing Counters into buckets as illustrated
- // below.
- //
- // Counter bucket: [1] [2] [3] [4-7] [8-15] [16-31] [32-127] [128+]
- // Feature number: 0 1 2 3 4 5 6 7
- //
- // This is a heuristic taken from AFL (see
- // http://lcamtuf.coredump.cx/afl/technical_details.txt).
- //
- // This implementation may change in the future so clients should
- // not rely on it.
- assert(Counter);
- unsigned Bit = 0;
- /**/ if (Counter >= 128) Bit = 7;
- else if (Counter >= 32) Bit = 6;
- else if (Counter >= 16) Bit = 5;
- else if (Counter >= 8) Bit = 4;
- else if (Counter >= 4) Bit = 3;
- else if (Counter >= 3) Bit = 2;
- else if (Counter >= 2) Bit = 1;
- return Bit;
-}
-
-template <class Callback> // void Callback(size_t Feature)
-ATTRIBUTE_NO_SANITIZE_ADDRESS
-ATTRIBUTE_NOINLINE
-void TracePC::CollectFeatures(Callback HandleFeature) const {
- auto Handle8bitCounter = [&](size_t FirstFeature,
- size_t Idx, uint8_t Counter) {
- if (UseCounters)
- HandleFeature(FirstFeature + Idx * 8 + CounterToFeature(Counter));
- else
- HandleFeature(FirstFeature + Idx);
- };
-
- size_t FirstFeature = 0;
-
- for (size_t i = 0; i < NumModules; i++) {
- for (size_t r = 0; r < Modules[i].NumRegions; r++) {
- if (!Modules[i].Regions[r].Enabled) continue;
- FirstFeature += 8 * ForEachNonZeroByte(Modules[i].Regions[r].Start,
- Modules[i].Regions[r].Stop,
- FirstFeature, Handle8bitCounter);
- }
- }
-
- FirstFeature +=
- 8 * ForEachNonZeroByte(ExtraCountersBegin(), ExtraCountersEnd(),
- FirstFeature, Handle8bitCounter);
-
- if (UseValueProfileMask) {
- ValueProfileMap.ForEach([&](size_t Idx) {
- HandleFeature(FirstFeature + Idx);
- });
- FirstFeature += ValueProfileMap.SizeInBits();
- }
-
- // Step function, grows similar to 8 * Log_2(A).
- auto StackDepthStepFunction = [](uint32_t A) -> uint32_t {
- if (!A) return A;
- uint32_t Log2 = Log(A);
- if (Log2 < 3) return A;
- Log2 -= 3;
- return (Log2 + 1) * 8 + ((A >> Log2) & 7);
- };
- assert(StackDepthStepFunction(1024) == 64);
- assert(StackDepthStepFunction(1024 * 4) == 80);
- assert(StackDepthStepFunction(1024 * 1024) == 144);
-
- if (auto MaxStackOffset = GetMaxStackOffset())
- HandleFeature(FirstFeature + StackDepthStepFunction(MaxStackOffset / 8));
-}
-
-extern TracePC TPC;
-
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_TRACE_PC
diff --git a/contrib/libs/libfuzzer12/FuzzerUtil.cpp b/contrib/libs/libfuzzer12/FuzzerUtil.cpp
deleted file mode 100644
index 7eecb68d072..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerUtil.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-//===- FuzzerUtil.cpp - Misc utils ----------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Misc utils.
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerUtil.h"
-#include "FuzzerIO.h"
-#include "FuzzerInternal.h"
-#include <cassert>
-#include <chrono>
-#include <cstring>
-#include <errno.h>
-#include <mutex>
-#include <signal.h>
-#include <sstream>
-#include <stdio.h>
-#include <sys/types.h>
-#include <thread>
-
-namespace fuzzer {
-
-void PrintHexArray(const uint8_t *Data, size_t Size,
- const char *PrintAfter) {
- for (size_t i = 0; i < Size; i++)
- Printf("0x%x,", (unsigned)Data[i]);
- Printf("%s", PrintAfter);
-}
-
-void Print(const Unit &v, const char *PrintAfter) {
- PrintHexArray(v.data(), v.size(), PrintAfter);
-}
-
-void PrintASCIIByte(uint8_t Byte) {
- if (Byte == '\\')
- Printf("\\\\");
- else if (Byte == '"')
- Printf("\\\"");
- else if (Byte >= 32 && Byte < 127)
- Printf("%c", Byte);
- else
- Printf("\\x%02x", Byte);
-}
-
-void PrintASCII(const uint8_t *Data, size_t Size, const char *PrintAfter) {
- for (size_t i = 0; i < Size; i++)
- PrintASCIIByte(Data[i]);
- Printf("%s", PrintAfter);
-}
-
-void PrintASCII(const Unit &U, const char *PrintAfter) {
- PrintASCII(U.data(), U.size(), PrintAfter);
-}
-
-bool ToASCII(uint8_t *Data, size_t Size) {
- bool Changed = false;
- for (size_t i = 0; i < Size; i++) {
- uint8_t &X = Data[i];
- auto NewX = X;
- NewX &= 127;
- if (!isspace(NewX) && !isprint(NewX))
- NewX = ' ';
- Changed |= NewX != X;
- X = NewX;
- }
- return Changed;
-}
-
-bool IsASCII(const Unit &U) { return IsASCII(U.data(), U.size()); }
-
-bool IsASCII(const uint8_t *Data, size_t Size) {
- for (size_t i = 0; i < Size; i++)
- if (!(isprint(Data[i]) || isspace(Data[i]))) return false;
- return true;
-}
-
-bool ParseOneDictionaryEntry(const std::string &Str, Unit *U) {
- U->clear();
- if (Str.empty()) return false;
- size_t L = 0, R = Str.size() - 1; // We are parsing the range [L,R].
- // Skip spaces from both sides.
- while (L < R && isspace(Str[L])) L++;
- while (R > L && isspace(Str[R])) R--;
- if (R - L < 2) return false;
- // Check the closing "
- if (Str[R] != '"') return false;
- R--;
- // Find the opening "
- while (L < R && Str[L] != '"') L++;
- if (L >= R) return false;
- assert(Str[L] == '\"');
- L++;
- assert(L <= R);
- for (size_t Pos = L; Pos <= R; Pos++) {
- uint8_t V = (uint8_t)Str[Pos];
- if (!isprint(V) && !isspace(V)) return false;
- if (V =='\\') {
- // Handle '\\'
- if (Pos + 1 <= R && (Str[Pos + 1] == '\\' || Str[Pos + 1] == '"')) {
- U->push_back(Str[Pos + 1]);
- Pos++;
- continue;
- }
- // Handle '\xAB'
- if (Pos + 3 <= R && Str[Pos + 1] == 'x'
- && isxdigit(Str[Pos + 2]) && isxdigit(Str[Pos + 3])) {
- char Hex[] = "0xAA";
- Hex[2] = Str[Pos + 2];
- Hex[3] = Str[Pos + 3];
- U->push_back(strtol(Hex, nullptr, 16));
- Pos += 3;
- continue;
- }
- return false; // Invalid escape.
- } else {
- // Any other character.
- U->push_back(V);
- }
- }
- return true;
-}
-
-bool ParseDictionaryFile(const std::string &Text, Vector<Unit> *Units) {
- if (Text.empty()) {
- Printf("ParseDictionaryFile: file does not exist or is empty\n");
- return false;
- }
- std::istringstream ISS(Text);
- Units->clear();
- Unit U;
- int LineNo = 0;
- std::string S;
- while (std::getline(ISS, S, '\n')) {
- LineNo++;
- size_t Pos = 0;
- while (Pos < S.size() && isspace(S[Pos])) Pos++; // Skip spaces.
- if (Pos == S.size()) continue; // Empty line.
- if (S[Pos] == '#') continue; // Comment line.
- if (ParseOneDictionaryEntry(S, &U)) {
- Units->push_back(U);
- } else {
- Printf("ParseDictionaryFile: error in line %d\n\t\t%s\n", LineNo,
- S.c_str());
- return false;
- }
- }
- return true;
-}
-
-// Code duplicated (and tested) in llvm/include/llvm/Support/Base64.h
-std::string Base64(const Unit &U) {
- static const char Table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789+/";
- std::string Buffer;
- Buffer.resize(((U.size() + 2) / 3) * 4);
-
- size_t i = 0, j = 0;
- for (size_t n = U.size() / 3 * 3; i < n; i += 3, j += 4) {
- uint32_t x = ((unsigned char)U[i] << 16) | ((unsigned char)U[i + 1] << 8) |
- (unsigned char)U[i + 2];
- Buffer[j + 0] = Table[(x >> 18) & 63];
- Buffer[j + 1] = Table[(x >> 12) & 63];
- Buffer[j + 2] = Table[(x >> 6) & 63];
- Buffer[j + 3] = Table[x & 63];
- }
- if (i + 1 == U.size()) {
- uint32_t x = ((unsigned char)U[i] << 16);
- Buffer[j + 0] = Table[(x >> 18) & 63];
- Buffer[j + 1] = Table[(x >> 12) & 63];
- Buffer[j + 2] = '=';
- Buffer[j + 3] = '=';
- } else if (i + 2 == U.size()) {
- uint32_t x = ((unsigned char)U[i] << 16) | ((unsigned char)U[i + 1] << 8);
- Buffer[j + 0] = Table[(x >> 18) & 63];
- Buffer[j + 1] = Table[(x >> 12) & 63];
- Buffer[j + 2] = Table[(x >> 6) & 63];
- Buffer[j + 3] = '=';
- }
- return Buffer;
-}
-
-static std::mutex SymbolizeMutex;
-
-std::string DescribePC(const char *SymbolizedFMT, uintptr_t PC) {
- std::unique_lock<std::mutex> l(SymbolizeMutex, std::try_to_lock);
- if (!EF->__sanitizer_symbolize_pc || !l.owns_lock())
- return "<can not symbolize>";
- char PcDescr[1024] = {};
- EF->__sanitizer_symbolize_pc(reinterpret_cast<void*>(PC),
- SymbolizedFMT, PcDescr, sizeof(PcDescr));
- PcDescr[sizeof(PcDescr) - 1] = 0; // Just in case.
- return PcDescr;
-}
-
-void PrintPC(const char *SymbolizedFMT, const char *FallbackFMT, uintptr_t PC) {
- if (EF->__sanitizer_symbolize_pc)
- Printf("%s", DescribePC(SymbolizedFMT, PC).c_str());
- else
- Printf(FallbackFMT, PC);
-}
-
-void PrintStackTrace() {
- std::unique_lock<std::mutex> l(SymbolizeMutex, std::try_to_lock);
- if (EF->__sanitizer_print_stack_trace && l.owns_lock())
- EF->__sanitizer_print_stack_trace();
-}
-
-void PrintMemoryProfile() {
- std::unique_lock<std::mutex> l(SymbolizeMutex, std::try_to_lock);
- if (EF->__sanitizer_print_memory_profile && l.owns_lock())
- EF->__sanitizer_print_memory_profile(95, 8);
-}
-
-unsigned NumberOfCpuCores() {
- unsigned N = std::thread::hardware_concurrency();
- if (!N) {
- Printf("WARNING: std::thread::hardware_concurrency not well defined for "
- "your platform. Assuming CPU count of 1.\n");
- N = 1;
- }
- return N;
-}
-
-size_t SimpleFastHash(const uint8_t *Data, size_t Size) {
- size_t Res = 0;
- for (size_t i = 0; i < Size; i++)
- Res = Res * 11 + Data[i];
- return Res;
-}
-
-} // namespace fuzzer
diff --git a/contrib/libs/libfuzzer12/FuzzerUtil.h b/contrib/libs/libfuzzer12/FuzzerUtil.h
deleted file mode 100644
index e90be085008..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerUtil.h
+++ /dev/null
@@ -1,117 +0,0 @@
-//===- FuzzerUtil.h - Internal header for the Fuzzer Utils ------*- 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
-//
-//===----------------------------------------------------------------------===//
-// Util functions.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_UTIL_H
-#define LLVM_FUZZER_UTIL_H
-
-#include "FuzzerBuiltins.h"
-#include "FuzzerBuiltinsMsvc.h"
-#include "FuzzerCommand.h"
-#include "FuzzerDefs.h"
-
-namespace fuzzer {
-
-void PrintHexArray(const Unit &U, const char *PrintAfter = "");
-
-void PrintHexArray(const uint8_t *Data, size_t Size,
- const char *PrintAfter = "");
-
-void PrintASCII(const uint8_t *Data, size_t Size, const char *PrintAfter = "");
-
-void PrintASCII(const Unit &U, const char *PrintAfter = "");
-
-// Changes U to contain only ASCII (isprint+isspace) characters.
-// Returns true iff U has been changed.
-bool ToASCII(uint8_t *Data, size_t Size);
-
-bool IsASCII(const Unit &U);
-
-bool IsASCII(const uint8_t *Data, size_t Size);
-
-std::string Base64(const Unit &U);
-
-void PrintPC(const char *SymbolizedFMT, const char *FallbackFMT, uintptr_t PC);
-
-std::string DescribePC(const char *SymbolizedFMT, uintptr_t PC);
-
-void PrintStackTrace();
-
-void PrintMemoryProfile();
-
-unsigned NumberOfCpuCores();
-
-// Platform specific functions.
-void SetSignalHandler(const FuzzingOptions& Options);
-
-void SleepSeconds(int Seconds);
-
-unsigned long GetPid();
-
-size_t GetPeakRSSMb();
-
-int ExecuteCommand(const Command &Cmd);
-bool ExecuteCommand(const Command &Cmd, std::string *CmdOutput);
-
-// Fuchsia does not have popen/pclose.
-FILE *OpenProcessPipe(const char *Command, const char *Mode);
-int CloseProcessPipe(FILE *F);
-
-const void *SearchMemory(const void *haystack, size_t haystacklen,
- const void *needle, size_t needlelen);
-
-std::string CloneArgsWithoutX(const Vector<std::string> &Args,
- const char *X1, const char *X2);
-
-inline std::string CloneArgsWithoutX(const Vector<std::string> &Args,
- const char *X) {
- return CloneArgsWithoutX(Args, X, X);
-}
-
-inline std::pair<std::string, std::string> SplitBefore(std::string X,
- std::string S) {
- auto Pos = S.find(X);
- if (Pos == std::string::npos)
- return std::make_pair(S, "");
- return std::make_pair(S.substr(0, Pos), S.substr(Pos));
-}
-
-void DiscardOutput(int Fd);
-
-std::string DisassembleCmd(const std::string &FileName);
-
-std::string SearchRegexCmd(const std::string &Regex);
-
-size_t SimpleFastHash(const uint8_t *Data, size_t Size);
-
-inline uint32_t Log(uint32_t X) { return 32 - Clz(X) - 1; }
-
-inline size_t PageSize() { return 4096; }
-inline uint8_t *RoundUpByPage(uint8_t *P) {
- uintptr_t X = reinterpret_cast<uintptr_t>(P);
- size_t Mask = PageSize() - 1;
- X = (X + Mask) & ~Mask;
- return reinterpret_cast<uint8_t *>(X);
-}
-inline uint8_t *RoundDownByPage(uint8_t *P) {
- uintptr_t X = reinterpret_cast<uintptr_t>(P);
- size_t Mask = PageSize() - 1;
- X = X & ~Mask;
- return reinterpret_cast<uint8_t *>(X);
-}
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-template <typename T> T HostToLE(T X) { return X; }
-#else
-template <typename T> T HostToLE(T X) { return Bswap(X); }
-#endif
-
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_UTIL_H
diff --git a/contrib/libs/libfuzzer12/FuzzerUtilDarwin.cpp b/contrib/libs/libfuzzer12/FuzzerUtilDarwin.cpp
deleted file mode 100644
index a5bed658a44..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerUtilDarwin.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-//===- FuzzerUtilDarwin.cpp - Misc utils ----------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Misc utils for Darwin.
-//===----------------------------------------------------------------------===//
-#include "FuzzerPlatform.h"
-#if LIBFUZZER_APPLE
-#include "FuzzerCommand.h"
-#include "FuzzerIO.h"
-#include <mutex>
-#include <signal.h>
-#include <spawn.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-// There is no header for this on macOS so declare here
-extern "C" char **environ;
-
-namespace fuzzer {
-
-static std::mutex SignalMutex;
-// Global variables used to keep track of how signal handling should be
-// restored. They should **not** be accessed without holding `SignalMutex`.
-static int ActiveThreadCount = 0;
-static struct sigaction OldSigIntAction;
-static struct sigaction OldSigQuitAction;
-static sigset_t OldBlockedSignalsSet;
-
-// This is a reimplementation of Libc's `system()`. On Darwin the Libc
-// implementation contains a mutex which prevents it from being used
-// concurrently. This implementation **can** be used concurrently. It sets the
-// signal handlers when the first thread enters and restores them when the last
-// thread finishes execution of the function and ensures this is not racey by
-// using a mutex.
-int ExecuteCommand(const Command &Cmd) {
- std::string CmdLine = Cmd.toString();
- posix_spawnattr_t SpawnAttributes;
- if (posix_spawnattr_init(&SpawnAttributes))
- return -1;
- // Block and ignore signals of the current process when the first thread
- // enters.
- {
- std::lock_guard<std::mutex> Lock(SignalMutex);
- if (ActiveThreadCount == 0) {
- static struct sigaction IgnoreSignalAction;
- sigset_t BlockedSignalsSet;
- memset(&IgnoreSignalAction, 0, sizeof(IgnoreSignalAction));
- IgnoreSignalAction.sa_handler = SIG_IGN;
-
- if (sigaction(SIGINT, &IgnoreSignalAction, &OldSigIntAction) == -1) {
- Printf("Failed to ignore SIGINT\n");
- (void)posix_spawnattr_destroy(&SpawnAttributes);
- return -1;
- }
- if (sigaction(SIGQUIT, &IgnoreSignalAction, &OldSigQuitAction) == -1) {
- Printf("Failed to ignore SIGQUIT\n");
- // Try our best to restore the signal handlers.
- (void)sigaction(SIGINT, &OldSigIntAction, NULL);
- (void)posix_spawnattr_destroy(&SpawnAttributes);
- return -1;
- }
-
- (void)sigemptyset(&BlockedSignalsSet);
- (void)sigaddset(&BlockedSignalsSet, SIGCHLD);
- if (sigprocmask(SIG_BLOCK, &BlockedSignalsSet, &OldBlockedSignalsSet) ==
- -1) {
- Printf("Failed to block SIGCHLD\n");
- // Try our best to restore the signal handlers.
- (void)sigaction(SIGQUIT, &OldSigQuitAction, NULL);
- (void)sigaction(SIGINT, &OldSigIntAction, NULL);
- (void)posix_spawnattr_destroy(&SpawnAttributes);
- return -1;
- }
- }
- ++ActiveThreadCount;
- }
-
- // NOTE: Do not introduce any new `return` statements past this
- // point. It is important that `ActiveThreadCount` always be decremented
- // when leaving this function.
-
- // Make sure the child process uses the default handlers for the
- // following signals rather than inheriting what the parent has.
- sigset_t DefaultSigSet;
- (void)sigemptyset(&DefaultSigSet);
- (void)sigaddset(&DefaultSigSet, SIGQUIT);
- (void)sigaddset(&DefaultSigSet, SIGINT);
- (void)posix_spawnattr_setsigdefault(&SpawnAttributes, &DefaultSigSet);
- // Make sure the child process doesn't block SIGCHLD
- (void)posix_spawnattr_setsigmask(&SpawnAttributes, &OldBlockedSignalsSet);
- short SpawnFlags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
- (void)posix_spawnattr_setflags(&SpawnAttributes, SpawnFlags);
-
- pid_t Pid;
- char **Environ = environ; // Read from global
- const char *CommandCStr = CmdLine.c_str();
- char *const Argv[] = {
- strdup("sh"),
- strdup("-c"),
- strdup(CommandCStr),
- NULL
- };
- int ErrorCode = 0, ProcessStatus = 0;
- // FIXME: We probably shouldn't hardcode the shell path.
- ErrorCode = posix_spawn(&Pid, "/bin/sh", NULL, &SpawnAttributes,
- Argv, Environ);
- (void)posix_spawnattr_destroy(&SpawnAttributes);
- if (!ErrorCode) {
- pid_t SavedPid = Pid;
- do {
- // Repeat until call completes uninterrupted.
- Pid = waitpid(SavedPid, &ProcessStatus, /*options=*/0);
- } while (Pid == -1 && errno == EINTR);
- if (Pid == -1) {
- // Fail for some other reason.
- ProcessStatus = -1;
- }
- } else if (ErrorCode == ENOMEM || ErrorCode == EAGAIN) {
- // Fork failure.
- ProcessStatus = -1;
- } else {
- // Shell execution failure.
- ProcessStatus = W_EXITCODE(127, 0);
- }
- for (unsigned i = 0, n = sizeof(Argv) / sizeof(Argv[0]); i < n; ++i)
- free(Argv[i]);
-
- // Restore the signal handlers of the current process when the last thread
- // using this function finishes.
- {
- std::lock_guard<std::mutex> Lock(SignalMutex);
- --ActiveThreadCount;
- if (ActiveThreadCount == 0) {
- bool FailedRestore = false;
- if (sigaction(SIGINT, &OldSigIntAction, NULL) == -1) {
- Printf("Failed to restore SIGINT handling\n");
- FailedRestore = true;
- }
- if (sigaction(SIGQUIT, &OldSigQuitAction, NULL) == -1) {
- Printf("Failed to restore SIGQUIT handling\n");
- FailedRestore = true;
- }
- if (sigprocmask(SIG_BLOCK, &OldBlockedSignalsSet, NULL) == -1) {
- Printf("Failed to unblock SIGCHLD\n");
- FailedRestore = true;
- }
- if (FailedRestore)
- ProcessStatus = -1;
- }
- }
- return ProcessStatus;
-}
-
-void DiscardOutput(int Fd) {
- FILE* Temp = fopen("/dev/null", "w");
- if (!Temp)
- return;
- dup2(fileno(Temp), Fd);
- fclose(Temp);
-}
-
-} // namespace fuzzer
-
-#endif // LIBFUZZER_APPLE
diff --git a/contrib/libs/libfuzzer12/FuzzerUtilLinux.cpp b/contrib/libs/libfuzzer12/FuzzerUtilLinux.cpp
deleted file mode 100644
index 981f9a8b429..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerUtilLinux.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-//===- FuzzerUtilLinux.cpp - Misc utils for Linux. ------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Misc utils for Linux.
-//===----------------------------------------------------------------------===//
-#include "FuzzerPlatform.h"
-#if LIBFUZZER_LINUX || LIBFUZZER_NETBSD || LIBFUZZER_FREEBSD || \
- LIBFUZZER_EMSCRIPTEN
-#include "FuzzerCommand.h"
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-
-namespace fuzzer {
-
-int ExecuteCommand(const Command &Cmd) {
- std::string CmdLine = Cmd.toString();
- int exit_code = system(CmdLine.c_str());
- if (WIFEXITED(exit_code))
- return WEXITSTATUS(exit_code);
- return exit_code;
-}
-
-void DiscardOutput(int Fd) {
- FILE* Temp = fopen("/dev/null", "w");
- if (!Temp)
- return;
- dup2(fileno(Temp), Fd);
- fclose(Temp);
-}
-
-} // namespace fuzzer
-
-#endif
diff --git a/contrib/libs/libfuzzer12/FuzzerUtilPosix.cpp b/contrib/libs/libfuzzer12/FuzzerUtilPosix.cpp
deleted file mode 100644
index afb733409ab..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerUtilPosix.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-//===- FuzzerUtilPosix.cpp - Misc utils for Posix. ------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Misc utils implementation using Posix API.
-//===----------------------------------------------------------------------===//
-#include "FuzzerPlatform.h"
-#if LIBFUZZER_POSIX
-#include "FuzzerIO.h"
-#include "FuzzerInternal.h"
-#include "FuzzerTracePC.h"
-#include <cassert>
-#include <chrono>
-#include <cstring>
-#include <errno.h>
-#include <iomanip>
-#include <signal.h>
-#include <stdio.h>
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <sys/syscall.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <thread>
-#include <unistd.h>
-
-namespace fuzzer {
-
-static void AlarmHandler(int, siginfo_t *, void *) {
- Fuzzer::StaticAlarmCallback();
-}
-
-static void (*upstream_segv_handler)(int, siginfo_t *, void *);
-
-static void SegvHandler(int sig, siginfo_t *si, void *ucontext) {
- assert(si->si_signo == SIGSEGV);
- if (upstream_segv_handler)
- return upstream_segv_handler(sig, si, ucontext);
- Fuzzer::StaticCrashSignalCallback();
-}
-
-static void CrashHandler(int, siginfo_t *, void *) {
- Fuzzer::StaticCrashSignalCallback();
-}
-
-static void InterruptHandler(int, siginfo_t *, void *) {
- Fuzzer::StaticInterruptCallback();
-}
-
-static void GracefulExitHandler(int, siginfo_t *, void *) {
- Fuzzer::StaticGracefulExitCallback();
-}
-
-static void FileSizeExceedHandler(int, siginfo_t *, void *) {
- Fuzzer::StaticFileSizeExceedCallback();
-}
-
-static void SetSigaction(int signum,
- void (*callback)(int, siginfo_t *, void *)) {
- struct sigaction sigact = {};
- if (sigaction(signum, nullptr, &sigact)) {
- Printf("libFuzzer: sigaction failed with %d\n", errno);
- exit(1);
- }
- if (sigact.sa_flags & SA_SIGINFO) {
- if (sigact.sa_sigaction) {
- if (signum != SIGSEGV)
- return;
- upstream_segv_handler = sigact.sa_sigaction;
- }
- } else {
- if (sigact.sa_handler != SIG_DFL && sigact.sa_handler != SIG_IGN &&
- sigact.sa_handler != SIG_ERR)
- return;
- }
-
- sigact = {};
- sigact.sa_flags = SA_SIGINFO;
- sigact.sa_sigaction = callback;
- if (sigaction(signum, &sigact, 0)) {
- Printf("libFuzzer: sigaction failed with %d\n", errno);
- exit(1);
- }
-}
-
-// Return true on success, false otherwise.
-bool ExecuteCommand(const Command &Cmd, std::string *CmdOutput) {
- FILE *Pipe = popen(Cmd.toString().c_str(), "r");
- if (!Pipe)
- return false;
-
- if (CmdOutput) {
- char TmpBuffer[128];
- while (fgets(TmpBuffer, sizeof(TmpBuffer), Pipe))
- CmdOutput->append(TmpBuffer);
- }
- return pclose(Pipe) == 0;
-}
-
-void SetTimer(int Seconds) {
- struct itimerval T {
- {Seconds, 0}, { Seconds, 0 }
- };
- if (setitimer(ITIMER_REAL, &T, nullptr)) {
- Printf("libFuzzer: setitimer failed with %d\n", errno);
- exit(1);
- }
- SetSigaction(SIGALRM, AlarmHandler);
-}
-
-void SetSignalHandler(const FuzzingOptions& Options) {
- // setitimer is not implemented in emscripten.
- if (Options.HandleAlrm && Options.UnitTimeoutSec > 0 && !LIBFUZZER_EMSCRIPTEN)
- SetTimer(Options.UnitTimeoutSec / 2 + 1);
- if (Options.HandleInt)
- SetSigaction(SIGINT, InterruptHandler);
- if (Options.HandleTerm)
- SetSigaction(SIGTERM, InterruptHandler);
- if (Options.HandleSegv)
- SetSigaction(SIGSEGV, SegvHandler);
- if (Options.HandleBus)
- SetSigaction(SIGBUS, CrashHandler);
- if (Options.HandleAbrt)
- SetSigaction(SIGABRT, CrashHandler);
- if (Options.HandleIll)
- SetSigaction(SIGILL, CrashHandler);
- if (Options.HandleFpe)
- SetSigaction(SIGFPE, CrashHandler);
- if (Options.HandleXfsz)
- SetSigaction(SIGXFSZ, FileSizeExceedHandler);
- if (Options.HandleUsr1)
- SetSigaction(SIGUSR1, GracefulExitHandler);
- if (Options.HandleUsr2)
- SetSigaction(SIGUSR2, GracefulExitHandler);
-}
-
-void SleepSeconds(int Seconds) {
- sleep(Seconds); // Use C API to avoid coverage from instrumented libc++.
-}
-
-unsigned long GetPid() { return (unsigned long)getpid(); }
-
-size_t GetPeakRSSMb() {
- struct rusage usage;
- if (getrusage(RUSAGE_SELF, &usage))
- return 0;
- if (LIBFUZZER_LINUX || LIBFUZZER_FREEBSD || LIBFUZZER_NETBSD ||
- LIBFUZZER_EMSCRIPTEN) {
- // ru_maxrss is in KiB
- return usage.ru_maxrss >> 10;
- } else if (LIBFUZZER_APPLE) {
- // ru_maxrss is in bytes
- return usage.ru_maxrss >> 20;
- }
- assert(0 && "GetPeakRSSMb() is not implemented for your platform");
- return 0;
-}
-
-FILE *OpenProcessPipe(const char *Command, const char *Mode) {
- return popen(Command, Mode);
-}
-
-int CloseProcessPipe(FILE *F) {
- return pclose(F);
-}
-
-const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt,
- size_t PattLen) {
- return memmem(Data, DataLen, Patt, PattLen);
-}
-
-std::string DisassembleCmd(const std::string &FileName) {
- return "objdump -d " + FileName;
-}
-
-std::string SearchRegexCmd(const std::string &Regex) {
- return "grep '" + Regex + "'";
-}
-
-} // namespace fuzzer
-
-#endif // LIBFUZZER_POSIX
diff --git a/contrib/libs/libfuzzer12/FuzzerUtilWindows.cpp b/contrib/libs/libfuzzer12/FuzzerUtilWindows.cpp
deleted file mode 100644
index 1a54bb569ec..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerUtilWindows.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-//===- FuzzerUtilWindows.cpp - Misc utils for Windows. --------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-// Misc utils implementation for Windows.
-//===----------------------------------------------------------------------===//
-#include "FuzzerPlatform.h"
-#if LIBFUZZER_WINDOWS
-#include "FuzzerCommand.h"
-#include "FuzzerIO.h"
-#include "FuzzerInternal.h"
-#include <cassert>
-#include <chrono>
-#include <cstring>
-#include <errno.h>
-#include <io.h>
-#include <iomanip>
-#include <signal.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <windows.h>
-
-// This must be included after windows.h.
-#include <psapi.h>
-
-namespace fuzzer {
-
-static const FuzzingOptions* HandlerOpt = nullptr;
-
-static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) {
- switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
- case EXCEPTION_ACCESS_VIOLATION:
- case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
- case EXCEPTION_STACK_OVERFLOW:
- if (HandlerOpt->HandleSegv)
- Fuzzer::StaticCrashSignalCallback();
- break;
- case EXCEPTION_DATATYPE_MISALIGNMENT:
- case EXCEPTION_IN_PAGE_ERROR:
- if (HandlerOpt->HandleBus)
- Fuzzer::StaticCrashSignalCallback();
- break;
- case EXCEPTION_ILLEGAL_INSTRUCTION:
- case EXCEPTION_PRIV_INSTRUCTION:
- if (HandlerOpt->HandleIll)
- Fuzzer::StaticCrashSignalCallback();
- break;
- case EXCEPTION_FLT_DENORMAL_OPERAND:
- case EXCEPTION_FLT_DIVIDE_BY_ZERO:
- case EXCEPTION_FLT_INEXACT_RESULT:
- case EXCEPTION_FLT_INVALID_OPERATION:
- case EXCEPTION_FLT_OVERFLOW:
- case EXCEPTION_FLT_STACK_CHECK:
- case EXCEPTION_FLT_UNDERFLOW:
- case EXCEPTION_INT_DIVIDE_BY_ZERO:
- case EXCEPTION_INT_OVERFLOW:
- if (HandlerOpt->HandleFpe)
- Fuzzer::StaticCrashSignalCallback();
- break;
- // This is an undocumented exception code corresponding to a Visual C++
- // Exception.
- //
- // See: https://devblogs.microsoft.com/oldnewthing/20100730-00/?p=13273
- case 0xE06D7363:
- if (HandlerOpt->HandleWinExcept)
- Fuzzer::StaticCrashSignalCallback();
- break;
- // TODO: Handle (Options.HandleXfsz)
- }
- return EXCEPTION_CONTINUE_SEARCH;
-}
-
-BOOL WINAPI CtrlHandler(DWORD dwCtrlType) {
- switch (dwCtrlType) {
- case CTRL_C_EVENT:
- if (HandlerOpt->HandleInt)
- Fuzzer::StaticInterruptCallback();
- return TRUE;
- case CTRL_BREAK_EVENT:
- if (HandlerOpt->HandleTerm)
- Fuzzer::StaticInterruptCallback();
- return TRUE;
- }
- return FALSE;
-}
-
-void CALLBACK AlarmHandler(PVOID, BOOLEAN) {
- Fuzzer::StaticAlarmCallback();
-}
-
-class TimerQ {
- HANDLE TimerQueue;
- public:
- TimerQ() : TimerQueue(NULL) {}
- ~TimerQ() {
- if (TimerQueue)
- DeleteTimerQueueEx(TimerQueue, NULL);
- }
- void SetTimer(int Seconds) {
- if (!TimerQueue) {
- TimerQueue = CreateTimerQueue();
- if (!TimerQueue) {
- Printf("libFuzzer: CreateTimerQueue failed.\n");
- exit(1);
- }
- }
- HANDLE Timer;
- if (!CreateTimerQueueTimer(&Timer, TimerQueue, AlarmHandler, NULL,
- Seconds*1000, Seconds*1000, 0)) {
- Printf("libFuzzer: CreateTimerQueueTimer failed.\n");
- exit(1);
- }
- }
-};
-
-static TimerQ Timer;
-
-static void CrashHandler(int) { Fuzzer::StaticCrashSignalCallback(); }
-
-void SetSignalHandler(const FuzzingOptions& Options) {
- HandlerOpt = &Options;
-
- if (Options.HandleAlrm && Options.UnitTimeoutSec > 0)
- Timer.SetTimer(Options.UnitTimeoutSec / 2 + 1);
-
- if (Options.HandleInt || Options.HandleTerm)
- if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) {
- DWORD LastError = GetLastError();
- Printf("libFuzzer: SetConsoleCtrlHandler failed (Error code: %lu).\n",
- LastError);
- exit(1);
- }
-
- if (Options.HandleSegv || Options.HandleBus || Options.HandleIll ||
- Options.HandleFpe || Options.HandleWinExcept)
- SetUnhandledExceptionFilter(ExceptionHandler);
-
- if (Options.HandleAbrt)
- if (SIG_ERR == signal(SIGABRT, CrashHandler)) {
- Printf("libFuzzer: signal failed with %d\n", errno);
- exit(1);
- }
-}
-
-void SleepSeconds(int Seconds) { Sleep(Seconds * 1000); }
-
-unsigned long GetPid() { return GetCurrentProcessId(); }
-
-size_t GetPeakRSSMb() {
- PROCESS_MEMORY_COUNTERS info;
- if (!GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)))
- return 0;
- return info.PeakWorkingSetSize >> 20;
-}
-
-FILE *OpenProcessPipe(const char *Command, const char *Mode) {
- return _popen(Command, Mode);
-}
-
-int CloseProcessPipe(FILE *F) {
- return _pclose(F);
-}
-
-int ExecuteCommand(const Command &Cmd) {
- std::string CmdLine = Cmd.toString();
- return system(CmdLine.c_str());
-}
-
-bool ExecuteCommand(const Command &Cmd, std::string *CmdOutput) {
- FILE *Pipe = _popen(Cmd.toString().c_str(), "r");
- if (!Pipe)
- return false;
-
- if (CmdOutput) {
- char TmpBuffer[128];
- while (fgets(TmpBuffer, sizeof(TmpBuffer), Pipe))
- CmdOutput->append(TmpBuffer);
- }
- return _pclose(Pipe) == 0;
-}
-
-const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt,
- size_t PattLen) {
- // TODO: make this implementation more efficient.
- const char *Cdata = (const char *)Data;
- const char *Cpatt = (const char *)Patt;
-
- if (!Data || !Patt || DataLen == 0 || PattLen == 0 || DataLen < PattLen)
- return NULL;
-
- if (PattLen == 1)
- return memchr(Data, *Cpatt, DataLen);
-
- const char *End = Cdata + DataLen - PattLen + 1;
-
- for (const char *It = Cdata; It < End; ++It)
- if (It[0] == Cpatt[0] && memcmp(It, Cpatt, PattLen) == 0)
- return It;
-
- return NULL;
-}
-
-std::string DisassembleCmd(const std::string &FileName) {
- Vector<std::string> command_vector;
- command_vector.push_back("dumpbin /summary > nul");
- if (ExecuteCommand(Command(command_vector)) == 0)
- return "dumpbin /disasm " + FileName;
- Printf("libFuzzer: couldn't find tool to disassemble (dumpbin)\n");
- exit(1);
-}
-
-std::string SearchRegexCmd(const std::string &Regex) {
- return "findstr /r \"" + Regex + "\"";
-}
-
-void DiscardOutput(int Fd) {
- FILE* Temp = fopen("nul", "w");
- if (!Temp)
- return;
- _dup2(_fileno(Temp), Fd);
- fclose(Temp);
-}
-
-} // namespace fuzzer
-
-#endif // LIBFUZZER_WINDOWS
diff --git a/contrib/libs/libfuzzer12/FuzzerValueBitMap.h b/contrib/libs/libfuzzer12/FuzzerValueBitMap.h
deleted file mode 100644
index ddbfe200af9..00000000000
--- a/contrib/libs/libfuzzer12/FuzzerValueBitMap.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//===- FuzzerValueBitMap.h - INTERNAL - Bit map -----------------*- 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
-//
-//===----------------------------------------------------------------------===//
-// ValueBitMap.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUZZER_VALUE_BIT_MAP_H
-#define LLVM_FUZZER_VALUE_BIT_MAP_H
-
-#include "FuzzerPlatform.h"
-#include <cstdint>
-
-namespace fuzzer {
-
-// A bit map containing kMapSizeInWords bits.
-struct ValueBitMap {
- static const size_t kMapSizeInBits = 1 << 16;
- static const size_t kMapPrimeMod = 65371; // Largest Prime < kMapSizeInBits;
- static const size_t kBitsInWord = (sizeof(uintptr_t) * 8);
- static const size_t kMapSizeInWords = kMapSizeInBits / kBitsInWord;
- public:
-
- // Clears all bits.
- void Reset() { memset(Map, 0, sizeof(Map)); }
-
- // Computes a hash function of Value and sets the corresponding bit.
- // Returns true if the bit was changed from 0 to 1.
- ATTRIBUTE_NO_SANITIZE_ALL
- inline bool AddValue(uintptr_t Value) {
- uintptr_t Idx = Value % kMapSizeInBits;
- uintptr_t WordIdx = Idx / kBitsInWord;
- uintptr_t BitIdx = Idx % kBitsInWord;
- uintptr_t Old = Map[WordIdx];
- uintptr_t New = Old | (1ULL << BitIdx);
- Map[WordIdx] = New;
- return New != Old;
- }
-
- ATTRIBUTE_NO_SANITIZE_ALL
- inline bool AddValueModPrime(uintptr_t Value) {
- return AddValue(Value % kMapPrimeMod);
- }
-
- inline bool Get(uintptr_t Idx) {
- assert(Idx < kMapSizeInBits);
- uintptr_t WordIdx = Idx / kBitsInWord;
- uintptr_t BitIdx = Idx % kBitsInWord;
- return Map[WordIdx] & (1ULL << BitIdx);
- }
-
- size_t SizeInBits() const { return kMapSizeInBits; }
-
- template <class Callback>
- ATTRIBUTE_NO_SANITIZE_ALL
- void ForEach(Callback CB) const {
- for (size_t i = 0; i < kMapSizeInWords; i++)
- if (uintptr_t M = Map[i])
- for (size_t j = 0; j < sizeof(M) * 8; j++)
- if (M & ((uintptr_t)1 << j))
- CB(i * sizeof(M) * 8 + j);
- }
-
- private:
- ATTRIBUTE_ALIGNED(512) uintptr_t Map[kMapSizeInWords];
-};
-
-} // namespace fuzzer
-
-#endif // LLVM_FUZZER_VALUE_BIT_MAP_H
diff --git a/contrib/libs/libfuzzer12/LICENSE.TXT b/contrib/libs/libfuzzer12/LICENSE.TXT
deleted file mode 100644
index 5a79a1b9d5c..00000000000
--- a/contrib/libs/libfuzzer12/LICENSE.TXT
+++ /dev/null
@@ -1,311 +0,0 @@
-==============================================================================
-The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
-==============================================================================
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-
----- LLVM Exceptions to the Apache 2.0 License ----
-
-As an exception, if, as a result of your compiling your source code, portions
-of this Software are embedded into an Object form of such source code, you
-may redistribute such embedded portions in such Object form without complying
-with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
-
-In addition, if you combine or link compiled forms of this Software with
-software that is licensed under the GPLv2 ("Combined Software") and if a
-court of competent jurisdiction determines that the patent provision (Section
-3), the indemnity provision (Section 9) or other Section of the License
-conflicts with the conditions of the GPLv2, you may retroactively and
-prospectively choose to deem waived or otherwise exclude such Section(s) of
-the License, but only in their entirety and only with respect to the Combined
-Software.
-
-==============================================================================
-Software from third parties included in the LLVM Project:
-==============================================================================
-The LLVM Project contains third party software which is under different license
-terms. All such code will be identified clearly using at least one of two
-mechanisms:
-1) It will be in a separate directory tree with its own `LICENSE.txt` or
- `LICENSE` file at the top containing the specific license and restrictions
- which apply to that software, or
-2) It will contain specific license and restriction terms at the top of every
- file.
-
-==============================================================================
-Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
-==============================================================================
-
-The compiler_rt library is dual licensed under both the University of Illinois
-"BSD-Like" license and the MIT license. As a user of this code you may choose
-to use it under either license. As a contributor, you agree to allow your code
-to be used under both.
-
-Full text of the relevant licenses is included below.
-
-==============================================================================
-
-University of Illinois/NCSA
-Open Source License
-
-Copyright (c) 2009-2019 by the contributors listed in CREDITS.TXT
-
-All rights reserved.
-
-Developed by:
-
- LLVM Team
-
- University of Illinois at Urbana-Champaign
-
- http://llvm.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal with
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimers.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimers in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the names of the LLVM Team, University of Illinois at
- Urbana-Champaign, nor the names of its contributors may be used to
- endorse or promote products derived from this Software without specific
- prior written permission.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
-SOFTWARE.
-
-==============================================================================
-
-Copyright (c) 2009-2015 by the contributors listed in CREDITS.TXT
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/contrib/libs/libfuzzer12/README.txt b/contrib/libs/libfuzzer12/README.txt
deleted file mode 100644
index 3eee01c7767..00000000000
--- a/contrib/libs/libfuzzer12/README.txt
+++ /dev/null
@@ -1 +0,0 @@
-See http://llvm.org/docs/LibFuzzer.html