diff options
54 files changed, 299 insertions, 808 deletions
diff --git a/gnu/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h b/gnu/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h index 0e734a8170b..e0592219463 100644 --- a/gnu/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h +++ b/gnu/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h @@ -10,28 +10,21 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPESERIALIZER_H #define LLVM_DEBUGINFO_CODEVIEW_TYPESERIALIZER_H -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/CodeView/RecordSerialization.h" -#include "llvm/DebugInfo/CodeView/TypeIndex.h" -#include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" +#include "llvm/DebugInfo/MSF/ByteStream.h" +#include "llvm/DebugInfo/MSF/StreamWriter.h" + +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" -#include "llvm/Support/BinaryByteStream.h" -#include "llvm/Support/BinaryStreamWriter.h" #include "llvm/Support/Error.h" -#include <cassert> -#include <cstdint> -#include <memory> -#include <vector> namespace llvm { -namespace codeview { -class TypeHasher; +namespace codeview { class TypeSerializer : public TypeVisitorCallbacks { struct SubRecord { @@ -52,54 +45,43 @@ class TypeSerializer : public TypeVisitorCallbacks { } }; - using MutableRecordList = SmallVector<MutableArrayRef<uint8_t>, 2>; + typedef SmallVector<MutableArrayRef<uint8_t>, 2> RecordList; static constexpr uint8_t ContinuationLength = 8; BumpPtrAllocator &RecordStorage; RecordSegment CurrentSegment; - MutableRecordList FieldListSegments; + RecordList FieldListSegments; + TypeIndex LastTypeIndex; Optional<TypeLeafKind> TypeKind; Optional<TypeLeafKind> MemberKind; std::vector<uint8_t> RecordBuffer; - MutableBinaryByteStream Stream; - BinaryStreamWriter Writer; + msf::MutableByteStream Stream; + msf::StreamWriter Writer; TypeRecordMapping Mapping; - /// Private type record hashing implementation details are handled here. - std::unique_ptr<TypeHasher> Hasher; - - /// Contains a list of all records indexed by TypeIndex.toArrayIndex(). - SmallVector<ArrayRef<uint8_t>, 2> SeenRecords; - - /// Temporary storage that we use to copy a record's data while re-writing - /// its type indices. - SmallVector<uint8_t, 256> RemapStorage; - - TypeIndex nextTypeIndex() const; + RecordList SeenRecords; + StringMap<TypeIndex> HashedRecords; bool isInFieldList() const; + TypeIndex calcNextTypeIndex() const; + TypeIndex incrementTypeIndex(); MutableArrayRef<uint8_t> getCurrentSubRecordData(); MutableArrayRef<uint8_t> getCurrentRecordData(); Error writeRecordPrefix(TypeLeafKind Kind); + TypeIndex insertRecordBytesPrivate(MutableArrayRef<uint8_t> Record); Expected<MutableArrayRef<uint8_t>> addPadding(MutableArrayRef<uint8_t> Record); public: - explicit TypeSerializer(BumpPtrAllocator &Storage, bool Hash = true); - ~TypeSerializer() override; + explicit TypeSerializer(BumpPtrAllocator &Storage); - void reset(); - - BumpPtrAllocator &getAllocator() { return RecordStorage; } - - ArrayRef<ArrayRef<uint8_t>> records() const; - TypeIndex insertRecordBytes(ArrayRef<uint8_t> &Record); - TypeIndex insertRecord(const RemappedType &Record); + ArrayRef<MutableArrayRef<uint8_t>> records() const; + TypeIndex getLastTypeIndex() const; + TypeIndex insertRecordBytes(MutableArrayRef<uint8_t> Record); Expected<TypeIndex> visitTypeEndGetIndex(CVType &Record); - using TypeVisitorCallbacks::visitTypeBegin; Error visitTypeBegin(CVType &Record) override; Error visitTypeEnd(CVType &Record) override; Error visitMemberBegin(CVMemberRecord &Record) override; @@ -115,7 +97,7 @@ public: return visitKnownMemberImpl<Name##Record>(CVR, Record); \ } #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" +#include "llvm/DebugInfo/CodeView/TypeRecords.def" private: template <typename RecordKind> @@ -152,8 +134,7 @@ private: return Error::success(); } }; +} +} -} // end namespace codeview -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_CODEVIEW_TYPESERIALIZER_H +#endif diff --git a/gnu/llvm/lib/CodeGen/CountingFunctionInserter.cpp b/gnu/llvm/lib/CodeGen/CountingFunctionInserter.cpp index 7f7350f5fb5..1e46a7a99e7 100644 --- a/gnu/llvm/lib/CodeGen/CountingFunctionInserter.cpp +++ b/gnu/llvm/lib/CodeGen/CountingFunctionInserter.cpp @@ -41,7 +41,7 @@ namespace { Type *VoidTy = Type::getVoidTy(F.getContext()); Constant *CountingFn = F.getParent()->getOrInsertFunction(CountingFunctionName, - VoidTy); + VoidTy, nullptr); CallInst::Create(CountingFn, "", &*F.begin()->getFirstInsertionPt()); return true; } diff --git a/gnu/llvm/lib/DebugInfo/CodeView/TypeSerializer.cpp b/gnu/llvm/lib/DebugInfo/CodeView/TypeSerializer.cpp index 003c13b4a20..f24fcff8627 100644 --- a/gnu/llvm/lib/DebugInfo/CodeView/TypeSerializer.cpp +++ b/gnu/llvm/lib/DebugInfo/CodeView/TypeSerializer.cpp @@ -1,4 +1,4 @@ -//===- TypeSerialzier.cpp -------------------------------------------------===// +//===- TypeSerialzier.cpp ---------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,136 +8,29 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/CodeView/TypeSerializer.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/CodeView/RecordSerialization.h" -#include "llvm/DebugInfo/CodeView/TypeIndex.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/BinaryByteStream.h" -#include "llvm/Support/BinaryStreamWriter.h" -#include "llvm/Support/Endian.h" -#include "llvm/Support/Error.h" -#include <algorithm> -#include <cassert> -#include <cstdint> -#include <cstring> -using namespace llvm; -using namespace llvm::codeview; - -namespace { - -struct HashedType { - uint64_t Hash; - const uint8_t *Data; - unsigned Size; // FIXME: Go to uint16_t? - TypeIndex Index; -}; - -/// Wrapper around a poitner to a HashedType. Hash and equality operations are -/// based on data in the pointee. -struct HashedTypePtr { - HashedTypePtr() = default; - HashedTypePtr(HashedType *Ptr) : Ptr(Ptr) {} - - HashedType *Ptr = nullptr; -}; - -} // end anonymous namespace +#include "llvm/DebugInfo/MSF/StreamWriter.h" -namespace llvm { +#include <string.h> -template <> struct DenseMapInfo<HashedTypePtr> { - static inline HashedTypePtr getEmptyKey() { return HashedTypePtr(nullptr); } - - static inline HashedTypePtr getTombstoneKey() { - return HashedTypePtr(reinterpret_cast<HashedType *>(1)); - } - - static unsigned getHashValue(HashedTypePtr Val) { - assert(Val.Ptr != getEmptyKey().Ptr && Val.Ptr != getTombstoneKey().Ptr); - return Val.Ptr->Hash; - } - - static bool isEqual(HashedTypePtr LHSP, HashedTypePtr RHSP) { - HashedType *LHS = LHSP.Ptr; - HashedType *RHS = RHSP.Ptr; - if (RHS == getEmptyKey().Ptr || RHS == getTombstoneKey().Ptr) - return LHS == RHS; - if (LHS->Hash != RHS->Hash || LHS->Size != RHS->Size) - return false; - return ::memcmp(LHS->Data, RHS->Data, LHS->Size) == 0; - } -}; - -} // end namespace llvm - -/// Private implementation so that we don't leak our DenseMap instantiations to -/// users. -class llvm::codeview::TypeHasher { -private: - /// Storage for type record provided by the caller. Records will outlive the - /// hasher object, so they should be allocated here. - BumpPtrAllocator &RecordStorage; - - /// Storage for hash keys. These only need to live as long as the hashing - /// operation. - BumpPtrAllocator KeyStorage; - - /// Hash table. We really want a DenseMap<ArrayRef<uint8_t>, TypeIndex> here, - /// but DenseMap is inefficient when the keys are long (like type records) - /// because it recomputes the hash value of every key when it grows. This - /// value type stores the hash out of line in KeyStorage, so that table - /// entries are small and easy to rehash. - DenseSet<HashedTypePtr> HashedRecords; - -public: - TypeHasher(BumpPtrAllocator &RecordStorage) : RecordStorage(RecordStorage) {} - - void reset() { HashedRecords.clear(); } - - /// Takes the bytes of type record, inserts them into the hash table, saves - /// them, and returns a pointer to an identical stable type record along with - /// its type index in the destination stream. - TypeIndex getOrCreateRecord(ArrayRef<uint8_t> &Record, TypeIndex TI); -}; - -TypeIndex TypeHasher::getOrCreateRecord(ArrayRef<uint8_t> &Record, - TypeIndex TI) { - assert(Record.size() < UINT32_MAX && "Record too big"); - assert(Record.size() % 4 == 0 && "Record is not aligned to 4 bytes!"); - - // Compute the hash up front so we can store it in the key. - HashedType TempHashedType = {hash_value(Record), Record.data(), - unsigned(Record.size()), TI}; - auto Result = HashedRecords.insert(HashedTypePtr(&TempHashedType)); - HashedType *&Hashed = Result.first->Ptr; - - if (Result.second) { - // This was a new type record. We need stable storage for both the key and - // the record. The record should outlive the hashing operation. - Hashed = KeyStorage.Allocate<HashedType>(); - *Hashed = TempHashedType; - - uint8_t *Stable = RecordStorage.Allocate<uint8_t>(Record.size()); - memcpy(Stable, Record.data(), Record.size()); - Hashed->Data = Stable; - assert(Hashed->Size == Record.size()); - } +using namespace llvm; +using namespace llvm::codeview; - // Update the caller's copy of Record to point a stable copy. - Record = ArrayRef<uint8_t>(Hashed->Data, Hashed->Size); - return Hashed->Index; +bool TypeSerializer::isInFieldList() const { + return TypeKind.hasValue() && *TypeKind == TypeLeafKind::LF_FIELDLIST; } -TypeIndex TypeSerializer::nextTypeIndex() const { - return TypeIndex::fromArrayIndex(SeenRecords.size()); +TypeIndex TypeSerializer::calcNextTypeIndex() const { + if (LastTypeIndex.isNoneType()) + return TypeIndex(TypeIndex::FirstNonSimpleIndex); + else + return TypeIndex(LastTypeIndex.getIndex() + 1); } -bool TypeSerializer::isInFieldList() const { - return TypeKind.hasValue() && *TypeKind == TypeLeafKind::LF_FIELDLIST; +TypeIndex TypeSerializer::incrementTypeIndex() { + TypeIndex Previous = LastTypeIndex; + LastTypeIndex = calcNextTypeIndex(); + return Previous; } MutableArrayRef<uint8_t> TypeSerializer::getCurrentSubRecordData() { @@ -158,6 +51,21 @@ Error TypeSerializer::writeRecordPrefix(TypeLeafKind Kind) { return Error::success(); } +TypeIndex +TypeSerializer::insertRecordBytesPrivate(MutableArrayRef<uint8_t> Record) { + assert(Record.size() % 4 == 0 && "Record is not aligned to 4 bytes!"); + + StringRef S(reinterpret_cast<const char *>(Record.data()), Record.size()); + + TypeIndex NextTypeIndex = calcNextTypeIndex(); + auto Result = HashedRecords.try_emplace(S, NextTypeIndex); + if (Result.second) { + LastTypeIndex = NextTypeIndex; + SeenRecords.push_back(Record); + } + return Result.first->getValue(); +} + Expected<MutableArrayRef<uint8_t>> TypeSerializer::addPadding(MutableArrayRef<uint8_t> Record) { uint32_t Align = Record.size() % 4; @@ -175,79 +83,26 @@ TypeSerializer::addPadding(MutableArrayRef<uint8_t> Record) { return MutableArrayRef<uint8_t>(Record.data(), Record.size() + N); } -TypeSerializer::TypeSerializer(BumpPtrAllocator &Storage, bool Hash) - : RecordStorage(Storage), RecordBuffer(MaxRecordLength * 2), - Stream(RecordBuffer, support::little), Writer(Stream), +TypeSerializer::TypeSerializer(BumpPtrAllocator &Storage) + : RecordStorage(Storage), LastTypeIndex(), + RecordBuffer(MaxRecordLength * 2), Stream(RecordBuffer), Writer(Stream), Mapping(Writer) { // RecordBuffer needs to be able to hold enough data so that if we are 1 // byte short of MaxRecordLen, and then we try to write MaxRecordLen bytes, // we won't overflow. - if (Hash) - Hasher = llvm::make_unique<TypeHasher>(Storage); } -TypeSerializer::~TypeSerializer() = default; - -ArrayRef<ArrayRef<uint8_t>> TypeSerializer::records() const { +ArrayRef<MutableArrayRef<uint8_t>> TypeSerializer::records() const { return SeenRecords; } -void TypeSerializer::reset() { - if (Hasher) - Hasher->reset(); - Writer.setOffset(0); - CurrentSegment = RecordSegment(); - FieldListSegments.clear(); - TypeKind.reset(); - MemberKind.reset(); - SeenRecords.clear(); -} - -TypeIndex TypeSerializer::insertRecordBytes(ArrayRef<uint8_t> &Record) { - assert(!TypeKind.hasValue() && "Already in a type mapping!"); - assert(Writer.getOffset() == 0 && "Stream has data already!"); - - if (Hasher) { - TypeIndex ActualTI = Hasher->getOrCreateRecord(Record, nextTypeIndex()); - if (nextTypeIndex() == ActualTI) - SeenRecords.push_back(Record); - return ActualTI; - } - - TypeIndex NewTI = nextTypeIndex(); - uint8_t *Stable = RecordStorage.Allocate<uint8_t>(Record.size()); - memcpy(Stable, Record.data(), Record.size()); - Record = ArrayRef<uint8_t>(Stable, Record.size()); - SeenRecords.push_back(Record); - return NewTI; -} +TypeIndex TypeSerializer::getLastTypeIndex() const { return LastTypeIndex; } -TypeIndex TypeSerializer::insertRecord(const RemappedType &Record) { +TypeIndex TypeSerializer::insertRecordBytes(MutableArrayRef<uint8_t> Record) { assert(!TypeKind.hasValue() && "Already in a type mapping!"); assert(Writer.getOffset() == 0 && "Stream has data already!"); - TypeIndex TI; - ArrayRef<uint8_t> OriginalData = Record.OriginalRecord.RecordData; - if (Record.Mappings.empty()) { - // This record did not remap any type indices. Just write it. - return insertRecordBytes(OriginalData); - } - - // At least one type index was remapped. Before we can hash it we have to - // copy the full record bytes, re-write each type index, then hash the copy. - // We do this in temporary storage since only the DenseMap can decide whether - // this record already exists, and if it does we don't want the memory to - // stick around. - RemapStorage.resize(OriginalData.size()); - ::memcpy(&RemapStorage[0], OriginalData.data(), OriginalData.size()); - uint8_t *ContentBegin = RemapStorage.data() + sizeof(RecordPrefix); - for (const auto &M : Record.Mappings) { - // First 4 bytes of every record are the record prefix, but the mapping - // offset is relative to the content which starts after. - *(TypeIndex *)(ContentBegin + M.first) = M.second; - } - auto RemapRef = makeArrayRef(RemapStorage); - return insertRecordBytes(RemapRef); + return insertRecordBytesPrivate(Record); } Error TypeSerializer::visitTypeBegin(CVType &Record) { @@ -281,14 +136,11 @@ Expected<TypeIndex> TypeSerializer::visitTypeEndGetIndex(CVType &Record) { reinterpret_cast<RecordPrefix *>(ThisRecordData.data()); Prefix->RecordLen = ThisRecordData.size() - sizeof(uint16_t); - Record.Type = *TypeKind; - Record.RecordData = ThisRecordData; - - // insertRecordBytes assumes we're not in a mapping, so do this first. - TypeKind.reset(); - Writer.setOffset(0); - - TypeIndex InsertedTypeIndex = insertRecordBytes(Record.RecordData); + uint8_t *Copy = RecordStorage.Allocate<uint8_t>(ThisRecordData.size()); + ::memcpy(Copy, ThisRecordData.data(), ThisRecordData.size()); + ThisRecordData = MutableArrayRef<uint8_t>(Copy, ThisRecordData.size()); + Record = CVType(*TypeKind, ThisRecordData); + TypeIndex InsertedTypeIndex = insertRecordBytesPrivate(ThisRecordData); // Write out each additional segment in reverse order, and update each // record's continuation index to point to the previous one. @@ -298,9 +150,11 @@ Expected<TypeIndex> TypeSerializer::visitTypeEndGetIndex(CVType &Record) { reinterpret_cast<support::ulittle32_t *>(CIBytes.data()); assert(*CI == 0xB0C0B0C0 && "Invalid TypeIndex placeholder"); *CI = InsertedTypeIndex.getIndex(); - InsertedTypeIndex = insertRecordBytes(X); + InsertedTypeIndex = insertRecordBytesPrivate(X); } + TypeKind.reset(); + Writer.setOffset(0); FieldListSegments.clear(); CurrentSegment.SubRecords.clear(); @@ -349,15 +203,15 @@ Error TypeSerializer::visitMemberEnd(CVMemberRecord &Record) { uint8_t *SegmentBytes = RecordStorage.Allocate<uint8_t>(LengthWithSize); auto SavedSegment = MutableArrayRef<uint8_t>(SegmentBytes, LengthWithSize); - MutableBinaryByteStream CS(SavedSegment, support::little); - BinaryStreamWriter CW(CS); + msf::MutableByteStream CS(SavedSegment); + msf::StreamWriter CW(CS); if (auto EC = CW.writeBytes(CopyData)) return EC; if (auto EC = CW.writeEnum(TypeLeafKind::LF_INDEX)) return EC; - if (auto EC = CW.writeInteger<uint16_t>(0)) + if (auto EC = CW.writeInteger(uint16_t(0))) return EC; - if (auto EC = CW.writeInteger<uint32_t>(0xB0C0B0C0)) + if (auto EC = CW.writeInteger(uint32_t(0xB0C0B0C0))) return EC; FieldListSegments.push_back(SavedSegment); diff --git a/gnu/llvm/lib/Fuzzer/FuzzerCorpus.h b/gnu/llvm/lib/Fuzzer/FuzzerCorpus.h index bae0aea78f1..468d5e5ddc7 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerCorpus.h +++ b/gnu/llvm/lib/Fuzzer/FuzzerCorpus.h @@ -34,13 +34,11 @@ struct InputInfo { size_t NumExecutedMutations = 0; size_t NumSuccessfullMutations = 0; bool MayDeleteFile = false; - bool Reduced = false; - std::vector<uint32_t> UniqFeatureSet; }; class InputCorpus { - static const size_t kFeatureSetSize = 1 << 21; public: + static const size_t kFeatureSetSize = 1 << 16; InputCorpus(const std::string &OutputCorpus) : OutputCorpus(OutputCorpus) { memset(InputSizesPerFeature, 0, sizeof(InputSizesPerFeature)); memset(SmallestElementPerFeature, 0, sizeof(SmallestElementPerFeature)); @@ -70,70 +68,21 @@ class InputCorpus { } bool empty() const { return Inputs.empty(); } const Unit &operator[] (size_t Idx) const { return Inputs[Idx]->U; } - void AddToCorpus(const Unit &U, size_t NumFeatures, bool MayDeleteFile, - const std::vector<uint32_t> &FeatureSet) { + void AddToCorpus(const Unit &U, size_t NumFeatures, bool MayDeleteFile = false) { assert(!U.empty()); + uint8_t Hash[kSHA1NumBytes]; if (FeatureDebug) Printf("ADD_TO_CORPUS %zd NF %zd\n", Inputs.size(), NumFeatures); + ComputeSHA1(U.data(), U.size(), Hash); + Hashes.insert(Sha1ToString(Hash)); Inputs.push_back(new InputInfo()); InputInfo &II = *Inputs.back(); II.U = U; II.NumFeatures = NumFeatures; II.MayDeleteFile = MayDeleteFile; - II.UniqFeatureSet = FeatureSet; - std::sort(II.UniqFeatureSet.begin(), II.UniqFeatureSet.end()); - ComputeSHA1(U.data(), U.size(), II.Sha1); - Hashes.insert(Sha1ToString(II.Sha1)); + memcpy(II.Sha1, Hash, kSHA1NumBytes); UpdateCorpusDistribution(); - PrintCorpus(); - // ValidateFeatureSet(); - } - - // 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 std::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; + ValidateFeatureSet(); } bool HasUnit(const Unit &U) { return Hashes.count(Hash(U)); } @@ -148,7 +97,7 @@ class InputCorpus { // Hypothesis: units added to the corpus last are more likely to be // interesting. This function gives more weight to the more recent units. size_t ChooseUnitIdxToMutate(Random &Rand) { - size_t Idx = static_cast<size_t>(CorpusDistribution(Rand)); + size_t Idx = static_cast<size_t>(CorpusDistribution(Rand.Get_mt19937())); assert(Idx < Inputs.size()); return Idx; } @@ -174,14 +123,10 @@ class InputCorpus { 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); + if (!OutputCorpus.empty() && II.MayDeleteFile) + RemoveFile(DirPlusFile(OutputCorpus, Sha1ToString(II.Sha1))); Unit().swap(II.U); if (FeatureDebug) Printf("EVICTED %zd\n", Idx); @@ -199,21 +144,23 @@ class InputCorpus { II.NumFeatures--; if (II.NumFeatures == 0) DeleteInput(OldIdx); - } else { - NumAddedFeatures++; } - NumUpdatedFeatures++; if (FeatureDebug) Printf("ADD FEATURE %zd sz %d\n", Idx, NewSize); SmallestElementPerFeature[Idx] = Inputs.size(); InputSizesPerFeature[Idx] = NewSize; + CountingFeatures = true; return true; } return false; } - size_t NumFeatures() const { return NumAddedFeatures; } - size_t NumFeatureUpdates() const { return NumUpdatedFeatures; } + size_t NumFeatures() const { + size_t Res = 0; + for (size_t i = 0; i < kFeatureSetSize; i++) + Res += GetFeature(i) != 0; + return Res; + } void ResetFeatureSet() { assert(Inputs.empty()); @@ -228,6 +175,7 @@ private: size_t GetFeature(size_t Idx) const { return InputSizesPerFeature[Idx]; } void ValidateFeatureSet() { + if (!CountingFeatures) return; if (FeatureDebug) PrintFeatureSet(); for (size_t Idx = 0; Idx < kFeatureSetSize; Idx++) @@ -245,12 +193,14 @@ private: // Must be called whenever the corpus or unit weights are changed. void UpdateCorpusDistribution() { size_t N = Inputs.size(); - assert(N); Intervals.resize(N + 1); Weights.resize(N); std::iota(Intervals.begin(), Intervals.end(), 0); - for (size_t i = 0; i < N; i++) - Weights[i] = Inputs[i]->NumFeatures * (i + 1); + if (CountingFeatures) + for (size_t i = 0; i < N; i++) + Weights[i] = Inputs[i]->NumFeatures * (i + 1); + else + std::iota(Weights.begin(), Weights.end(), 1); CorpusDistribution = std::piecewise_constant_distribution<double>( Intervals.begin(), Intervals.end(), Weights.begin()); } @@ -262,8 +212,7 @@ private: std::unordered_set<std::string> Hashes; std::vector<InputInfo*> Inputs; - size_t NumAddedFeatures = 0; - size_t NumUpdatedFeatures = 0; + bool CountingFeatures = false; uint32_t InputSizesPerFeature[kFeatureSetSize]; uint32_t SmallestElementPerFeature[kFeatureSetSize]; diff --git a/gnu/llvm/lib/Fuzzer/FuzzerDefs.h b/gnu/llvm/lib/Fuzzer/FuzzerDefs.h index 27f5719236d..0f5b8a7cf21 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerDefs.h +++ b/gnu/llvm/lib/Fuzzer/FuzzerDefs.h @@ -36,53 +36,19 @@ #error "Support for your platform has not been implemented" #endif -#ifndef __has_attribute -# define __has_attribute(x) 0 -#endif - #define LIBFUZZER_POSIX LIBFUZZER_APPLE || LIBFUZZER_LINUX #ifdef __x86_64 -# if __has_attribute(target) -# define ATTRIBUTE_TARGET_POPCNT __attribute__((target("popcnt"))) -# else -# define ATTRIBUTE_TARGET_POPCNT -# endif +#define ATTRIBUTE_TARGET_POPCNT __attribute__((target("popcnt"))) #else -# define ATTRIBUTE_TARGET_POPCNT +#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)) +# define ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory"))) #else # define ATTRIBUTE_NO_SANITIZE_MEMORY -# define ALWAYS_INLINE -#endif // __clang__ - -#define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) - -#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 - -#if LIBFUZZER_WINDOWS -#define ATTRIBUTE_INTERFACE __declspec(dllexport) -#else -#define ATTRIBUTE_INTERFACE __attribute__((visibility("default"))) #endif namespace fuzzer { @@ -108,10 +74,9 @@ typedef int (*UserCallback)(const uint8_t *Data, size_t Size); int FuzzerDriver(int *argc, char ***argv, UserCallback Callback); -struct ScopedDoingMyOwnMemOrStr { - ScopedDoingMyOwnMemOrStr() { DoingMyOwnMemOrStr++; } - ~ScopedDoingMyOwnMemOrStr() { DoingMyOwnMemOrStr--; } - static int DoingMyOwnMemOrStr; +struct ScopedDoingMyOwnMemmem { + ScopedDoingMyOwnMemmem(); + ~ScopedDoingMyOwnMemmem(); }; inline uint8_t Bswap(uint8_t x) { return x; } @@ -119,10 +84,6 @@ 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); } -uint8_t *ExtraCountersBegin(); -uint8_t *ExtraCountersEnd(); -void ClearExtraCounters(); - } // namespace fuzzer #endif // LLVM_FUZZER_DEFS_H diff --git a/gnu/llvm/lib/Fuzzer/FuzzerDictionary.h b/gnu/llvm/lib/Fuzzer/FuzzerDictionary.h index 84cee87b897..eba0eabb683 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerDictionary.h +++ b/gnu/llvm/lib/Fuzzer/FuzzerDictionary.h @@ -20,9 +20,8 @@ namespace fuzzer { // A simple POD sized array of bytes. -template <size_t kMaxSizeT> class FixedWord { +template <size_t kMaxSize> class FixedWord { public: - static const size_t kMaxSize = kMaxSizeT; FixedWord() {} FixedWord(const uint8_t *B, uint8_t S) { Set(B, S); } @@ -33,12 +32,10 @@ public: } bool operator==(const FixedWord<kMaxSize> &w) const { - ScopedDoingMyOwnMemOrStr scoped_doing_my_own_mem_os_str; return Size == w.Size && 0 == memcmp(Data, w.Data, Size); } bool operator<(const FixedWord<kMaxSize> &w) const { - ScopedDoingMyOwnMemOrStr scoped_doing_my_own_mem_os_str; if (Size != w.Size) return Size < w.Size; return memcmp(Data, w.Data, Size) < 0; @@ -53,7 +50,7 @@ private: uint8_t Data[kMaxSize]; }; -typedef FixedWord<64> Word; +typedef FixedWord<27> Word; // 28 bytes. class DictionaryEntry { public: diff --git a/gnu/llvm/lib/Fuzzer/FuzzerIO.h b/gnu/llvm/lib/Fuzzer/FuzzerIO.h index 3b66a52d1a6..15bfd3d3472 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerIO.h +++ b/gnu/llvm/lib/Fuzzer/FuzzerIO.h @@ -40,17 +40,12 @@ std::string DirName(const std::string &FileName); // Returns path to a TmpDir. std::string TmpDir(); -bool IsInterestingCoverageFile(const std::string &FileName); - void DupAndCloseStderr(); void CloseStdout(); void Printf(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); @@ -67,10 +62,6 @@ int DuplicateFile(int Fd); void RemoveFile(const std::string &Path); -void DiscardOutput(int Fd); - -intptr_t GetHandleFromFd(int fd); - } // namespace fuzzer #endif // LLVM_FUZZER_IO_H diff --git a/gnu/llvm/lib/Fuzzer/FuzzerIOPosix.cpp b/gnu/llvm/lib/Fuzzer/FuzzerIOPosix.cpp index c5ebdbac467..6d8edf6ff53 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerIOPosix.cpp +++ b/gnu/llvm/lib/Fuzzer/FuzzerIOPosix.cpp @@ -75,18 +75,6 @@ void RemoveFile(const std::string &Path) { unlink(Path.c_str()); } -void DiscardOutput(int Fd) { - FILE* Temp = fopen("/dev/null", "w"); - if (!Temp) - return; - dup2(fileno(Temp), Fd); - fclose(Temp); -} - -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); @@ -101,23 +89,6 @@ std::string TmpDir() { 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) { - write(2, Str, strlen(Str)); -} - } // namespace fuzzer #endif // LIBFUZZER_POSIX diff --git a/gnu/llvm/lib/Fuzzer/FuzzerIOWindows.cpp b/gnu/llvm/lib/Fuzzer/FuzzerIOWindows.cpp index 742520267b7..056f0721a33 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerIOWindows.cpp +++ b/gnu/llvm/lib/Fuzzer/FuzzerIOWindows.cpp @@ -89,10 +89,8 @@ void ListFilesInDirRecursive(const std::string &Dir, long *Epoch, HANDLE FindHandle(FindFirstFileA(Path.c_str(), &FindInfo)); if (FindHandle == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_FILE_NOT_FOUND) - return; - Printf("No such directory: %s; exiting\n", Dir.c_str()); - exit(1); + Printf("No file found in: %s.\n", Dir.c_str()); + return; } do { @@ -141,18 +139,6 @@ void RemoveFile(const std::string &Path) { _unlink(Path.c_str()); } -void DiscardOutput(int Fd) { - FILE* Temp = fopen("nul", "w"); - if (!Temp) - return; - _dup2(_fileno(Temp), Fd); - fclose(Temp); -} - -intptr_t GetHandleFromFd(int fd) { - return _get_osfhandle(fd); -} - static bool IsSeparator(char C) { return C == '\\' || C == '/'; } @@ -182,7 +168,7 @@ static size_t ParseFileName(const std::string &FileName, const size_t Offset) { return Pos - Offset; } -// Parse a directory ending in separator, like: `SomeDir\` +// 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; @@ -197,7 +183,7 @@ static size_t ParseDir(const std::string &FileName, const size_t Offset) { return Pos - Offset; } -// Parse a servername and share, like: `SomeServer\SomeShare\` +// 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) { @@ -291,32 +277,7 @@ std::string DirName(const std::string &FileName) { 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) { - // Not tested, may or may not work. Fix if needed. - Printf("%s", Str); -} +std::string TmpDir() { return "TODO: implement TmpDir"; } } // namespace fuzzer diff --git a/gnu/llvm/lib/Fuzzer/FuzzerMerge.cpp b/gnu/llvm/lib/Fuzzer/FuzzerMerge.cpp index 616c0999aa3..9e559115680 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerMerge.cpp +++ b/gnu/llvm/lib/Fuzzer/FuzzerMerge.cpp @@ -9,15 +9,14 @@ // Merging corpora. //===----------------------------------------------------------------------===// -#include "FuzzerMerge.h" -#include "FuzzerIO.h" #include "FuzzerInternal.h" +#include "FuzzerIO.h" +#include "FuzzerMerge.h" #include "FuzzerTracePC.h" #include "FuzzerUtil.h" #include <fstream> #include <iterator> -#include <set> #include <sstream> namespace fuzzer { @@ -74,7 +73,6 @@ bool Merger::Parse(std::istream &IS, bool ParseCoverage) { size_t ExpectedStartMarker = 0; const size_t kInvalidStartMarker = -1; size_t LastSeenStartMarker = kInvalidStartMarker; - std::vector<uint32_t> TmpFeatures; while (std::getline(IS, Line, '\n')) { std::istringstream ISS1(Line); std::string Marker; @@ -90,17 +88,17 @@ bool Merger::Parse(std::istream &IS, bool ParseCoverage) { assert(ExpectedStartMarker < Files.size()); ExpectedStartMarker++; } else if (Marker == "DONE") { - // DONE FILE_ID COV1 COV2 COV3 ... + // DONE FILE_SIZE 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. + auto &V = Files[CurrentFileIdx].Features; + V.clear(); while (ISS1 >> std::hex >> N) - TmpFeatures.push_back(N); - std::sort(TmpFeatures.begin(), TmpFeatures.end()); - Files[CurrentFileIdx].Features = TmpFeatures; + V.push_back(N); + std::sort(V.begin(), V.end()); } } else { return false; @@ -113,20 +111,12 @@ bool Merger::Parse(std::istream &IS, bool ParseCoverage) { 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 thost to NewFiles). // Returns the number of new features added. -size_t Merger::Merge(const std::set<uint32_t> &InitialFeatures, - std::vector<std::string> *NewFiles) { +size_t Merger::Merge(std::vector<std::string> *NewFiles) { NewFiles->clear(); assert(NumFilesInFirstCorpus <= Files.size()); - std::set<uint32_t> AllFeatures(InitialFeatures); + std::set<uint32_t> AllFeatures; // What features are in the initial corpus? for (size_t i = 0; i < NumFilesInFirstCorpus; i++) { @@ -168,42 +158,6 @@ size_t Merger::Merge(const std::set<uint32_t> &InitialFeatures, return AllFeatures.size() - InitialNumFeatures; } -void Merger::PrintSummary(std::ostream &OS) { - for (auto &File : Files) { - OS << std::hex; - OS << File.Name << " size: " << File.Size << " features: "; - for (auto Feature : File.Features) - OS << " " << Feature; - OS << "\n"; - } -} - -std::set<uint32_t> Merger::AllFeatures() const { - std::set<uint32_t> S; - for (auto &File : Files) - S.insert(File.Features.begin(), File.Features.end()); - return S; -} - -std::set<uint32_t> Merger::ParseSummary(std::istream &IS) { - std::string Line, Tmp; - std::set<uint32_t> Res; - while (std::getline(IS, Line, '\n')) { - size_t N; - std::istringstream ISS1(Line); - ISS1 >> Tmp; // Name - ISS1 >> Tmp; // size: - assert(Tmp == "size:" && "Corrupt summary file"); - ISS1 >> std::hex; - ISS1 >> N; // File Size - ISS1 >> Tmp; // features: - assert(Tmp == "features:" && "Corrupt summary file"); - while (ISS1 >> std::hex >> N) - Res.insert(N); - } - return Res; -} - // 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()); @@ -241,6 +195,7 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) { return true; }); // Show stats. + TotalNumberOfRuns++; if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1))) PrintStats("pulse "); // Write the post-run marker and the coverage. @@ -253,9 +208,7 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) { // Outer process. Does not call the target code and thus sohuld not fail. void Fuzzer::CrashResistantMerge(const std::vector<std::string> &Args, - const std::vector<std::string> &Corpora, - const char *CoverageSummaryInputPathOrNull, - const char *CoverageSummaryOutputPathOrNull) { + const std::vector<std::string> &Corpora) { if (Corpora.size() <= 1) { Printf("Merge requires two or more corpus dirs\n"); return; @@ -285,23 +238,16 @@ void Fuzzer::CrashResistantMerge(const std::vector<std::string> &Args, // Execute the inner process untill it passes. // Every inner process should execute at least one input. - auto BaseCmd = SplitBefore("-ignore_remaining_args=1", - CloneArgsWithoutX(Args, "keep-all-flags")); - bool Success = false; + std::string BaseCmd = CloneArgsWithoutX(Args, "keep-all-flags"); for (size_t i = 1; i <= AllFiles.size(); i++) { Printf("MERGE-OUTER: attempt %zd\n", i); - auto ExitCode = ExecuteCommand(BaseCmd.first + " -merge_control_file=" + - CFPath + " " + BaseCmd.second); + auto ExitCode = + ExecuteCommand(BaseCmd + " -merge_control_file=" + CFPath); if (!ExitCode) { Printf("MERGE-OUTER: succesfull in %zd attempt(s)\n", i); - Success = true; break; } } - if (!Success) { - Printf("MERGE-OUTER: zero succesfull attempts, exiting\n"); - exit(1); - } // Read the control file and do the merge. Merger M; std::ifstream IF(CFPath); @@ -310,23 +256,8 @@ void Fuzzer::CrashResistantMerge(const std::vector<std::string> &Args, IF.seekg(0, IF.beg); M.ParseOrExit(IF, true); IF.close(); - Printf("MERGE-OUTER: consumed %zdMb (%zdMb rss) to parse the control file\n", - M.ApproximateMemoryConsumption() >> 20, GetPeakRSSMb()); - if (CoverageSummaryOutputPathOrNull) { - Printf("MERGE-OUTER: writing coverage summary for %zd files to %s\n", - M.Files.size(), CoverageSummaryOutputPathOrNull); - std::ofstream SummaryOut(CoverageSummaryOutputPathOrNull); - M.PrintSummary(SummaryOut); - } std::vector<std::string> NewFiles; - std::set<uint32_t> InitialFeatures; - if (CoverageSummaryInputPathOrNull) { - std::ifstream SummaryIn(CoverageSummaryInputPathOrNull); - InitialFeatures = M.ParseSummary(SummaryIn); - Printf("MERGE-OUTER: coverage summary loaded from %s, %zd features found\n", - CoverageSummaryInputPathOrNull, InitialFeatures.size()); - } - size_t NumNewFeatures = M.Merge(InitialFeatures, &NewFiles); + size_t NumNewFeatures = M.Merge(&NewFiles); Printf("MERGE-OUTER: %zd new files with %zd new features added\n", NewFiles.size(), NumNewFeatures); for (auto &F: NewFiles) diff --git a/gnu/llvm/lib/Fuzzer/FuzzerMerge.h b/gnu/llvm/lib/Fuzzer/FuzzerMerge.h index dd4c37b6e39..8a2fe5d74f8 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerMerge.h +++ b/gnu/llvm/lib/Fuzzer/FuzzerMerge.h @@ -43,9 +43,7 @@ #include "FuzzerDefs.h" #include <istream> -#include <ostream> #include <set> -#include <vector> namespace fuzzer { @@ -64,15 +62,7 @@ struct Merger { bool Parse(std::istream &IS, bool ParseCoverage); bool Parse(const std::string &Str, bool ParseCoverage); void ParseOrExit(std::istream &IS, bool ParseCoverage); - void PrintSummary(std::ostream &OS); - std::set<uint32_t> ParseSummary(std::istream &IS); - size_t Merge(const std::set<uint32_t> &InitialFeatures, - std::vector<std::string> *NewFiles); - size_t Merge(std::vector<std::string> *NewFiles) { - return Merge(std::set<uint32_t>{}, NewFiles); - } - size_t ApproximateMemoryConsumption() const; - std::set<uint32_t> AllFeatures() const; + size_t Merge(std::vector<std::string> *NewFiles); }; } // namespace fuzzer diff --git a/gnu/llvm/lib/Fuzzer/FuzzerMutate.h b/gnu/llvm/lib/Fuzzer/FuzzerMutate.h index 84b04c0dbf3..d3c0b001246 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerMutate.h +++ b/gnu/llvm/lib/Fuzzer/FuzzerMutate.h @@ -14,7 +14,6 @@ #include "FuzzerDefs.h" #include "FuzzerDictionary.h" -#include "FuzzerOptions.h" #include "FuzzerRandom.h" namespace fuzzer { @@ -52,6 +51,10 @@ public: size_t Mutate_AddWordFromManualDictionary(uint8_t *Data, size_t Size, size_t MaxSize); + /// Mutates data by adding a word from the temporary automatic dictionary. + size_t Mutate_AddWordFromTemporaryAutoDictionary(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); @@ -80,6 +83,8 @@ public: void AddWordToManualDictionary(const Word &W); + void AddWordToAutoDictionary(DictionaryEntry DE); + void ClearAutoDictionary(); void PrintRecommendedDictionary(); void SetCorpus(const InputCorpus *Corpus) { this->Corpus = Corpus; } @@ -108,16 +113,9 @@ private: 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; + const FuzzingOptions &Options; // Dictionary provided by the user via -dict=DICT_FILE. Dictionary ManualDictionary; @@ -137,9 +135,6 @@ private: const InputCorpus *Corpus = nullptr; std::vector<uint8_t> MutateInPlaceHere; - // CustomCrossOver needs its own buffer as a custom implementation may call - // LLVMFuzzerMutate, which in turn may resize MutateInPlaceHere. - std::vector<uint8_t> CustomCrossOverInPlaceHere; std::vector<Mutator> Mutators; std::vector<Mutator> DefaultMutators; diff --git a/gnu/llvm/lib/Fuzzer/FuzzerOptions.h b/gnu/llvm/lib/Fuzzer/FuzzerOptions.h index 9500235e2b1..6f72205600b 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerOptions.h +++ b/gnu/llvm/lib/Fuzzer/FuzzerOptions.h @@ -1,3 +1,4 @@ +//===- FuzzerOptions.h - Internal header for the Fuzzer ---------*- C++ -* ===// // // The LLVM Compiler Infrastructure // @@ -28,11 +29,11 @@ struct FuzzingOptions { int MutateDepth = 5; bool UseCounters = false; bool UseIndirCalls = true; + bool UseMemcmp = true; bool UseMemmem = true; bool UseCmp = false; bool UseValueProfile = false; bool Shrink = false; - bool ReduceInputs = false; int ReloadIntervalSec = 1; bool ShuffleAtStartUp = true; bool PreferSmall = true; @@ -46,6 +47,7 @@ struct FuzzingOptions { std::string ExitOnItem; bool SaveArtifacts = true; bool PrintNEW = true; // Print a status line when new units are found; + bool OutputCSV = false; bool PrintNewCovPcs = false; bool PrintFinalStats = false; bool PrintCorpusStats = false; diff --git a/gnu/llvm/lib/Fuzzer/FuzzerRandom.h b/gnu/llvm/lib/Fuzzer/FuzzerRandom.h index 8a1aa3ef5fd..b1be0bb935f 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerRandom.h +++ b/gnu/llvm/lib/Fuzzer/FuzzerRandom.h @@ -15,11 +15,10 @@ #include <random> namespace fuzzer { -class Random : public std::mt19937 { +class Random { public: - Random(unsigned int seed) : std::mt19937(seed) {} - result_type operator()() { return this->std::mt19937::operator()(); } - size_t Rand() { return this->operator()(); } + Random(unsigned int seed) : R(seed) {} + size_t Rand() { return R(); } size_t RandBool() { return Rand() % 2; } size_t operator()(size_t n) { return n ? Rand() % n : 0; } intptr_t operator()(intptr_t From, intptr_t To) { @@ -27,6 +26,9 @@ class Random : public std::mt19937 { intptr_t RangeSize = To - From + 1; return operator()(RangeSize) + From; } + std::mt19937 &Get_mt19937() { return R; } + private: + std::mt19937 R; }; } // namespace fuzzer diff --git a/gnu/llvm/lib/Fuzzer/FuzzerUtil.h b/gnu/llvm/lib/Fuzzer/FuzzerUtil.h index 62d6e61dcf1..08058c56e4c 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerUtil.h +++ b/gnu/llvm/lib/Fuzzer/FuzzerUtil.h @@ -67,20 +67,6 @@ inline std::string CloneArgsWithoutX(const std::vector<std::string> &Args, 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)); -} - -std::string DisassembleCmd(const std::string &FileName); - -std::string SearchRegexCmd(const std::string &Regex); - -size_t SimpleFastHash(const uint8_t *Data, size_t Size); - } // namespace fuzzer #endif // LLVM_FUZZER_UTIL_H diff --git a/gnu/llvm/lib/Fuzzer/FuzzerUtilDarwin.cpp b/gnu/llvm/lib/Fuzzer/FuzzerUtilDarwin.cpp index 2df4872a920..9674368c355 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerUtilDarwin.cpp +++ b/gnu/llvm/lib/Fuzzer/FuzzerUtilDarwin.cpp @@ -15,8 +15,6 @@ #include <mutex> #include <signal.h> #include <spawn.h> -#include <stdlib.h> -#include <string.h> #include <sys/wait.h> // There is no header for this on macOS so declare here @@ -99,16 +97,11 @@ int ExecuteCommand(const std::string &Command) { pid_t Pid; char **Environ = environ; // Read from global const char *CommandCStr = Command.c_str(); - char *const Argv[] = { - strdup("sh"), - strdup("-c"), - strdup(CommandCStr), - NULL - }; + const char *Argv[] = {"sh", "-c", 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); + (char *const *)Argv, Environ); (void)posix_spawnattr_destroy(&SpawnAttributes); if (!ErrorCode) { pid_t SavedPid = Pid; @@ -127,8 +120,6 @@ int ExecuteCommand(const std::string &Command) { // 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. diff --git a/gnu/llvm/lib/Fuzzer/FuzzerUtilPosix.cpp b/gnu/llvm/lib/Fuzzer/FuzzerUtilPosix.cpp index bc85264ac18..e8d48dc81a3 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerUtilPosix.cpp +++ b/gnu/llvm/lib/Fuzzer/FuzzerUtilPosix.cpp @@ -47,21 +47,8 @@ static void FileSizeExceedHandler(int, siginfo_t *, void *) { 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) - return; - } else { - if (sigact.sa_handler != SIG_DFL && sigact.sa_handler != SIG_IGN && - sigact.sa_handler != SIG_ERR) - return; - } - - sigact = {}; + struct sigaction sigact; + memset(&sigact, 0, sizeof(sigact)); sigact.sa_sigaction = callback; if (sigaction(signum, &sigact, 0)) { Printf("libFuzzer: sigaction failed with %d\n", errno); @@ -131,14 +118,6 @@ const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt, 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/gnu/llvm/lib/Fuzzer/FuzzerUtilWindows.cpp b/gnu/llvm/lib/Fuzzer/FuzzerUtilWindows.cpp index 25ac976fc2d..3ca1f2c8f56 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerUtilWindows.cpp +++ b/gnu/llvm/lib/Fuzzer/FuzzerUtilWindows.cpp @@ -22,15 +22,13 @@ #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) { +LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) { switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: @@ -128,7 +126,10 @@ void SetSignalHandler(const FuzzingOptions& Options) { if (Options.HandleSegv || Options.HandleBus || Options.HandleIll || Options.HandleFpe) - SetUnhandledExceptionFilter(ExceptionHandler); + if (!AddVectoredExceptionHandler(1, ExceptionHandler)) { + Printf("libFuzzer: AddVectoredExceptionHandler failed.\n"); + exit(1); + } if (Options.HandleAbrt) if (SIG_ERR == signal(SIGABRT, CrashHandler)) { @@ -177,17 +178,6 @@ const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt, return NULL; } -std::string DisassembleCmd(const std::string &FileName) { - if (ExecuteCommand("dumpbin /summary > nul") == 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 + "\""; -} - } // namespace fuzzer #endif // LIBFUZZER_WINDOWS diff --git a/gnu/llvm/lib/Fuzzer/FuzzerValueBitMap.h b/gnu/llvm/lib/Fuzzer/FuzzerValueBitMap.h index 8f7ff74300f..0692acd13ee 100644 --- a/gnu/llvm/lib/Fuzzer/FuzzerValueBitMap.h +++ b/gnu/llvm/lib/Fuzzer/FuzzerValueBitMap.h @@ -18,20 +18,19 @@ 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 kMapSizeInBits = 65371; // Prime. + static const size_t kMapSizeInBitsAligned = 65536; // 2^16 static const size_t kBitsInWord = (sizeof(uintptr_t) * 8); - static const size_t kMapSizeInWords = kMapSizeInBits / kBitsInWord; + static const size_t kMapSizeInWords = kMapSizeInBitsAligned / kBitsInWord; public: - + static const size_t kNumberOfItems = kMapSizeInBits; // 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 Idx = Value < kMapSizeInBits ? Value : Value % kMapSizeInBits; uintptr_t WordIdx = Idx / kBitsInWord; uintptr_t BitIdx = Idx % kBitsInWord; uintptr_t Old = Map[WordIdx]; @@ -40,11 +39,6 @@ struct ValueBitMap { 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; @@ -68,15 +62,14 @@ struct ValueBitMap { Other.Map[i] = 0; } if (M) - Res += __builtin_popcountll(M); + Res += __builtin_popcountl(M); } NumBits = Res; return OldNumBits < NumBits; } template <class Callback> - ATTRIBUTE_NO_SANITIZE_ALL - void ForEach(Callback CB) const { + void ForEach(Callback CB) { for (size_t i = 0; i < kMapSizeInWords; i++) if (uintptr_t M = Map[i]) for (size_t j = 0; j < sizeof(M) * 8; j++) diff --git a/gnu/llvm/lib/Fuzzer/build.sh b/gnu/llvm/lib/Fuzzer/build.sh index 4556af5daf7..27c148ad43d 100755 --- a/gnu/llvm/lib/Fuzzer/build.sh +++ b/gnu/llvm/lib/Fuzzer/build.sh @@ -1,8 +1,7 @@ #!/bin/bash LIBFUZZER_SRC_DIR=$(dirname $0) -CXX="${CXX:-clang}" for f in $LIBFUZZER_SRC_DIR/*.cpp; do - $CXX -g -O2 -fno-omit-frame-pointer -std=c++11 $f -c & + clang -g -O2 -fno-omit-frame-pointer -std=c++11 $f -c & done wait rm -f libFuzzer.a diff --git a/gnu/llvm/lib/Fuzzer/test/AbsNegAndConstant64Test.cpp b/gnu/llvm/lib/Fuzzer/test/AbsNegAndConstant64Test.cpp index b5a61ddca71..577481431ae 100644 --- a/gnu/llvm/lib/Fuzzer/test/AbsNegAndConstant64Test.cpp +++ b/gnu/llvm/lib/Fuzzer/test/AbsNegAndConstant64Test.cpp @@ -2,19 +2,19 @@ // License. See LICENSE.TXT for details. // abs(x) < 0 and y == Const puzzle, 64-bit variant. -#include <cstddef> +#include <cstring> #include <cstdint> -#include <cstdio> #include <cstdlib> -#include <cstring> +#include <cstddef> +#include <cstdio> extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - if (Size < 16 || Size > 64) return 0; + if (Size < 16) return 0; int64_t x; uint64_t y; memcpy(&x, Data, sizeof(x)); memcpy(&y, Data + sizeof(x), sizeof(y)); - if (llabs(x) < 0 && y == 0xbaddcafedeadbeefULL) { + if (labs(x) < 0 && y == 0xbaddcafedeadbeefUL) { printf("BINGO; Found the target, exiting; x = 0x%lx y 0x%lx\n", x, y); exit(1); } diff --git a/gnu/llvm/lib/Fuzzer/test/AbsNegAndConstantTest.cpp b/gnu/llvm/lib/Fuzzer/test/AbsNegAndConstantTest.cpp index e9d983ff1eb..69075a454c9 100644 --- a/gnu/llvm/lib/Fuzzer/test/AbsNegAndConstantTest.cpp +++ b/gnu/llvm/lib/Fuzzer/test/AbsNegAndConstantTest.cpp @@ -2,11 +2,11 @@ // License. See LICENSE.TXT for details. // abs(x) < 0 and y == Const puzzle. -#include <cstddef> +#include <cstring> #include <cstdint> -#include <cstdio> #include <cstdlib> -#include <cstring> +#include <cstddef> +#include <cstdio> extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { if (Size < 8) return 0; diff --git a/gnu/llvm/lib/Fuzzer/test/DSO1.cpp b/gnu/llvm/lib/Fuzzer/test/DSO1.cpp index 72a5ec4a0cd..4a293890f4b 100644 --- a/gnu/llvm/lib/Fuzzer/test/DSO1.cpp +++ b/gnu/llvm/lib/Fuzzer/test/DSO1.cpp @@ -2,9 +2,7 @@ // License. See LICENSE.TXT for details. // Source code for a simple DSO. -#ifdef _WIN32 -__declspec( dllexport ) -#endif + int DSO1(int a) { if (a < 123456) return 0; diff --git a/gnu/llvm/lib/Fuzzer/test/DSO2.cpp b/gnu/llvm/lib/Fuzzer/test/DSO2.cpp index 2967055dc22..04b308d193a 100644 --- a/gnu/llvm/lib/Fuzzer/test/DSO2.cpp +++ b/gnu/llvm/lib/Fuzzer/test/DSO2.cpp @@ -2,9 +2,7 @@ // License. See LICENSE.TXT for details. // Source code for a simple DSO. -#ifdef _WIN32 -__declspec( dllexport ) -#endif + int DSO2(int a) { if (a < 3598235) return 0; diff --git a/gnu/llvm/lib/Fuzzer/test/DSOTestMain.cpp b/gnu/llvm/lib/Fuzzer/test/DSOTestMain.cpp index e0c857d4fde..3e225d88612 100644 --- a/gnu/llvm/lib/Fuzzer/test/DSOTestMain.cpp +++ b/gnu/llvm/lib/Fuzzer/test/DSOTestMain.cpp @@ -4,9 +4,9 @@ // Source code for a simple DSO. #include <cstdint> -#include <cstdio> #include <cstdlib> #include <cstring> +#include <cstdio> extern int DSO1(int a); extern int DSO2(int a); extern int DSOTestExtra(int a); diff --git a/gnu/llvm/lib/Fuzzer/test/DivTest.cpp b/gnu/llvm/lib/Fuzzer/test/DivTest.cpp index bce13feb790..63f6960f4e9 100644 --- a/gnu/llvm/lib/Fuzzer/test/DivTest.cpp +++ b/gnu/llvm/lib/Fuzzer/test/DivTest.cpp @@ -3,9 +3,9 @@ // Simple test for a fuzzer: find the interesting argument for div. #include <assert.h> -#include <cstddef> #include <cstdint> #include <cstring> +#include <cstddef> #include <iostream> static volatile int Sink; diff --git a/gnu/llvm/lib/Fuzzer/test/LoadTest.cpp b/gnu/llvm/lib/Fuzzer/test/LoadTest.cpp index 67a28c7cb22..c1780d5c7bd 100644 --- a/gnu/llvm/lib/Fuzzer/test/LoadTest.cpp +++ b/gnu/llvm/lib/Fuzzer/test/LoadTest.cpp @@ -3,9 +3,9 @@ // Simple test for a fuzzer: find interesting value of array index. #include <assert.h> -#include <cstddef> #include <cstdint> #include <cstring> +#include <cstddef> #include <iostream> static volatile int Sink; @@ -14,7 +14,7 @@ int array[kArraySize]; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { if (Size < 8) return 0; - uint64_t a = 0; + size_t a = 0; memcpy(&a, Data, 8); Sink = array[a % (kArraySize + 1)]; return 0; diff --git a/gnu/llvm/lib/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp b/gnu/llvm/lib/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp index a07795a08df..ea23a601aa2 100644 --- a/gnu/llvm/lib/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp +++ b/gnu/llvm/lib/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp @@ -3,9 +3,9 @@ // Tests OOM handling. #include <assert.h> -#include <cstddef> #include <cstdint> #include <cstdlib> +#include <cstddef> #include <cstring> #include <iostream> @@ -15,7 +15,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { if (Size > 0 && Data[0] == 'H') { if (Size > 1 && Data[1] == 'i') { if (Size > 2 && Data[2] == '!') { - size_t kSize = 0x20000000U; + size_t kSize = 0xff000000U; char *p = new char[kSize]; SinkPtr = p; delete [] p; diff --git a/gnu/llvm/lib/Fuzzer/test/RepeatedBytesTest.cpp b/gnu/llvm/lib/Fuzzer/test/RepeatedBytesTest.cpp index 14222f28474..2fa6c78c26d 100644 --- a/gnu/llvm/lib/Fuzzer/test/RepeatedBytesTest.cpp +++ b/gnu/llvm/lib/Fuzzer/test/RepeatedBytesTest.cpp @@ -3,9 +3,9 @@ // Simple test for a fuzzer. The fuzzer must find repeated bytes. #include <assert.h> -#include <cstddef> #include <cstdint> #include <cstdlib> +#include <cstddef> #include <iostream> extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { diff --git a/gnu/llvm/lib/Fuzzer/test/ShrinkControlFlowTest.cpp b/gnu/llvm/lib/Fuzzer/test/ShrinkControlFlowTest.cpp index 37eeede7cbf..0fd7c5e9a1f 100644 --- a/gnu/llvm/lib/Fuzzer/test/ShrinkControlFlowTest.cpp +++ b/gnu/llvm/lib/Fuzzer/test/ShrinkControlFlowTest.cpp @@ -2,16 +2,15 @@ // License. See LICENSE.TXT for details. // Test that we can find the minimal item in the corpus (3 bytes: "FUZ"). -#include <cstddef> #include <cstdint> -#include <cstdio> #include <cstdlib> +#include <cstddef> #include <cstring> +#include <cstdio> static volatile int Sink; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - if (Size > 64) return 0; int8_t Ids[256]; memset(Ids, -1, sizeof(Ids)); for (size_t i = 0; i < Size; i++) diff --git a/gnu/llvm/lib/Fuzzer/test/ShrinkValueProfileTest.cpp b/gnu/llvm/lib/Fuzzer/test/ShrinkValueProfileTest.cpp index 86e4e3cb0d9..026b8ce2659 100644 --- a/gnu/llvm/lib/Fuzzer/test/ShrinkValueProfileTest.cpp +++ b/gnu/llvm/lib/Fuzzer/test/ShrinkValueProfileTest.cpp @@ -2,11 +2,11 @@ // License. See LICENSE.TXT for details. // Test that we can find the minimal item in the corpus (3 bytes: "FUZ"). -#include <cstddef> #include <cstdint> -#include <cstdio> #include <cstdlib> +#include <cstddef> #include <cstring> +#include <cstdio> static volatile uint32_t Sink; diff --git a/gnu/llvm/lib/Fuzzer/test/SingleMemcmpTest.cpp b/gnu/llvm/lib/Fuzzer/test/SingleMemcmpTest.cpp index 83c09e0428e..c73f68a7ee6 100644 --- a/gnu/llvm/lib/Fuzzer/test/SingleMemcmpTest.cpp +++ b/gnu/llvm/lib/Fuzzer/test/SingleMemcmpTest.cpp @@ -2,10 +2,10 @@ // License. See LICENSE.TXT for details. // Simple test for a fuzzer. The fuzzer must find a particular string. +#include <cstring> #include <cstdint> #include <cstdio> #include <cstdlib> -#include <cstring> extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { char *S = (char*)Data; diff --git a/gnu/llvm/lib/Fuzzer/test/SingleStrcmpTest.cpp b/gnu/llvm/lib/Fuzzer/test/SingleStrcmpTest.cpp index 149073444c9..73470b527ee 100644 --- a/gnu/llvm/lib/Fuzzer/test/SingleStrcmpTest.cpp +++ b/gnu/llvm/lib/Fuzzer/test/SingleStrcmpTest.cpp @@ -2,20 +2,16 @@ // License. See LICENSE.TXT for details. // Simple test for a fuzzer. The fuzzer must find a particular string. +#include <cstring> #include <cstdint> #include <cstdio> #include <cstdlib> -#include <cstring> extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - if (Size >= 7) { - char Copy[7]; - memcpy(Copy, Data, 6); - Copy[6] = 0; - if (!strcmp(Copy, "qwerty")) { - fprintf(stderr, "BINGO\n"); - exit(1); - } + char *S = (char*)Data; + if (Size >= 7 && !strcmp(S, "qwerty")) { + fprintf(stderr, "BINGO\n"); + exit(1); } return 0; } diff --git a/gnu/llvm/lib/Fuzzer/test/SingleStrncmpTest.cpp b/gnu/llvm/lib/Fuzzer/test/SingleStrncmpTest.cpp index b38c7995d8f..dbcc464b0a7 100644 --- a/gnu/llvm/lib/Fuzzer/test/SingleStrncmpTest.cpp +++ b/gnu/llvm/lib/Fuzzer/test/SingleStrncmpTest.cpp @@ -2,16 +2,14 @@ // License. See LICENSE.TXT for details. // Simple test for a fuzzer. The fuzzer must find a particular string. +#include <cstring> #include <cstdint> #include <cstdio> #include <cstdlib> -#include <cstring> extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - if (Size > 64) return 0; char *S = (char*)Data; - volatile auto Strncmp = &(strncmp); // Make sure strncmp is not inlined. - if (Size >= 6 && !Strncmp(S, "qwerty", 6)) { + if (Size >= 6 && !strncmp(S, "qwerty", 6)) { fprintf(stderr, "BINGO\n"); exit(1); } diff --git a/gnu/llvm/lib/Fuzzer/test/StrncmpOOBTest.cpp b/gnu/llvm/lib/Fuzzer/test/StrncmpOOBTest.cpp index 4ed71d9d021..f70b003afad 100644 --- a/gnu/llvm/lib/Fuzzer/test/StrncmpOOBTest.cpp +++ b/gnu/llvm/lib/Fuzzer/test/StrncmpOOBTest.cpp @@ -3,10 +3,10 @@ // Test that libFuzzer itself does not read out of bounds. #include <assert.h> -#include <cstddef> #include <cstdint> -#include <cstdlib> #include <cstring> +#include <cstdlib> +#include <cstddef> #include <iostream> static volatile int Sink; diff --git a/gnu/llvm/lib/Fuzzer/test/SwapCmpTest.cpp b/gnu/llvm/lib/Fuzzer/test/SwapCmpTest.cpp index bbfbefe6ab7..f79db4ccf71 100644 --- a/gnu/llvm/lib/Fuzzer/test/SwapCmpTest.cpp +++ b/gnu/llvm/lib/Fuzzer/test/SwapCmpTest.cpp @@ -3,9 +3,9 @@ // The fuzzer must find several constants with swapped bytes. #include <cstdint> -#include <cstdio> #include <cstdlib> #include <cstring> +#include <cstdio> extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { if (Size < 14) return 0; @@ -19,9 +19,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { x = __builtin_bswap64(x); y = __builtin_bswap32(y); z = __builtin_bswap16(z); - const bool k32bit = sizeof(void*) == 4; - if ((k32bit || x == 0x46555A5A5A5A5546ULL) && + if (x == 0x46555A5A5A5A5546ULL && z == 0x4F4B && y == 0x66757A7A && true diff --git a/gnu/llvm/lib/Fuzzer/test/Switch2Test.cpp b/gnu/llvm/lib/Fuzzer/test/Switch2Test.cpp index 5f66ac8b499..3c6a3004907 100644 --- a/gnu/llvm/lib/Fuzzer/test/Switch2Test.cpp +++ b/gnu/llvm/lib/Fuzzer/test/Switch2Test.cpp @@ -2,11 +2,11 @@ // License. See LICENSE.TXT for details. // Simple test for a fuzzer. The fuzzer must find the interesting switch value. -#include <cstddef> #include <cstdint> -#include <cstdio> #include <cstdlib> +#include <cstdio> #include <cstring> +#include <cstddef> int Switch(int a) { switch(a) { diff --git a/gnu/llvm/lib/Fuzzer/test/TimeoutEmptyTest.cpp b/gnu/llvm/lib/Fuzzer/test/TimeoutEmptyTest.cpp index 1ddf1fa3458..8066f480b65 100644 --- a/gnu/llvm/lib/Fuzzer/test/TimeoutEmptyTest.cpp +++ b/gnu/llvm/lib/Fuzzer/test/TimeoutEmptyTest.cpp @@ -2,8 +2,8 @@ // License. See LICENSE.TXT for details. // Simple test for a fuzzer. The fuzzer must find the empty string. -#include <cstddef> #include <cstdint> +#include <cstddef> extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { static volatile int Zero = 0; diff --git a/gnu/llvm/lib/Fuzzer/test/TraceMallocTest.cpp b/gnu/llvm/lib/Fuzzer/test/TraceMallocTest.cpp index af9975603aa..43e6950e185 100644 --- a/gnu/llvm/lib/Fuzzer/test/TraceMallocTest.cpp +++ b/gnu/llvm/lib/Fuzzer/test/TraceMallocTest.cpp @@ -3,9 +3,9 @@ // Tests -trace_malloc #include <assert.h> -#include <cstddef> #include <cstdint> #include <cstdlib> +#include <cstddef> #include <iostream> int *Ptr; diff --git a/gnu/llvm/lib/Fuzzer/test/coverage.test b/gnu/llvm/lib/Fuzzer/test/coverage.test index ff3fdff57a3..fa11be502ef 100644 --- a/gnu/llvm/lib/Fuzzer/test/coverage.test +++ b/gnu/llvm/lib/Fuzzer/test/coverage.test @@ -1,11 +1,9 @@ -XFAIL: darwin - CHECK: COVERAGE: CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:13 CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:14 CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:16 CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:19 -CHECK: COVERED_DIRS: {{.*}}lib{{[/\\]}}Fuzzer{{[/\\]}}test +CHECK: COVERED_DIRS: {{.*}}lib/Fuzzer/test RUN: not LLVMFuzzer-NullDerefTest -print_coverage=1 2>&1 | FileCheck %s RUN: LLVMFuzzer-DSOTest -print_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO diff --git a/gnu/llvm/lib/Fuzzer/test/dump_coverage.test b/gnu/llvm/lib/Fuzzer/test/dump_coverage.test index bd85ed718e1..9bd98daa361 100644 --- a/gnu/llvm/lib/Fuzzer/test/dump_coverage.test +++ b/gnu/llvm/lib/Fuzzer/test/dump_coverage.test @@ -1,14 +1,16 @@ -RUN: rm -rf %t_workdir && mkdir -p %t_workdir -RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' not LLVMFuzzer-NullDerefTest -dump_coverage=1 2>&1 | FileCheck %s -RUN: sancov -covered-functions LLVMFuzzer-NullDerefTest* %t_workdir/*.sancov | FileCheck %s --check-prefix=SANCOV -RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' LLVMFuzzer-DSOTest -dump_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO -RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' not LLVMFuzzer-NullDerefTest -dump_coverage=0 2>&1 | FileCheck %s --check-prefix=NOCOV - -CHECK: SanitizerCoverage: {{.*}}LLVMFuzzer-NullDerefTest.{{.*}}.sancov: {{.*}} PCs written -SANCOV: LLVMFuzzerTestOneInput - -DSO: SanitizerCoverage: {{.*}}LLVMFuzzer-DSOTest.{{.*}}.sancov: {{.*}} PCs written -DSO-DAG: SanitizerCoverage: {{.*}}LLVMFuzzer-DSO1.{{.*}}.sancov: {{.*}} PCs written -DSO-DAG: SanitizerCoverage: {{.*}}LLVMFuzzer-DSO2.{{.*}}.sancov: {{.*}} PCs written +RUN: DIR=%t_workdir +RUN: BUILD_DIR=$(pwd) +RUN: rm -rf $DIR && mkdir -p $DIR && cd $DIR +RUN: not $BUILD_DIR/LLVMFuzzer-NullDerefTest -dump_coverage=1 2>&1 | FileCheck %s +RUN: $BUILD_DIR/LLVMFuzzer-DSOTest -dump_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO +RUN: not $BUILD_DIR/LLVMFuzzer-NullDerefTest -dump_coverage=0 2>&1 | FileCheck %s --check-prefix=NOCOV +RUN: rm -rf $DIR + + +CHECK: SanitizerCoverage: ./LLVMFuzzer-NullDerefTest.{{.*}}.sancov {{.*}} PCs written + +DSO: SanitizerCoverage: ./LLVMFuzzer-DSOTest.{{.*}}.sancov {{.*}} PCs written +DSO-DAG: SanitizerCoverage: ./libLLVMFuzzer-DSO1.{{.*}}.sancov {{.*}} PCs written +DSO-DAG: SanitizerCoverage: ./libLLVMFuzzer-DSO2.{{.*}}.sancov {{.*}} PCs written NOCOV-NOT: SanitizerCoverage: {{.*}} PCs written diff --git a/gnu/llvm/lib/Fuzzer/test/minimize_crash.test b/gnu/llvm/lib/Fuzzer/test/minimize_crash.test index 5643c6bacb0..7e5406598e4 100644 --- a/gnu/llvm/lib/Fuzzer/test/minimize_crash.test +++ b/gnu/llvm/lib/Fuzzer/test/minimize_crash.test @@ -1,13 +1,6 @@ RUN: echo 'Hi!rv349f34t3gg' > not_minimal_crash RUN: LLVMFuzzer-NullDerefTest -minimize_crash=1 not_minimal_crash -max_total_time=2 2>&1 | FileCheck %s -CHECK: CRASH_MIN: failed to minimize beyond ./minimized-from-{{.*}} (3 bytes), exiting +CHECK: CRASH_MIN: failed to minimize beyond minimized-from-{{.*}} (3 bytes), exiting RUN: LLVMFuzzer-NullDerefTest -minimize_crash=1 not_minimal_crash -max_total_time=2 -exact_artifact_path=exact_minimized_path 2>&1 | FileCheck %s --check-prefix=CHECK_EXACT CHECK_EXACT: CRASH_MIN: failed to minimize beyond exact_minimized_path (3 bytes), exiting RUN: rm not_minimal_crash minimized-from-* exact_minimized_path - -RUN: echo -n 'abcd*xyz' > not_minimal_crash -RUN: LLVMFuzzer-SingleByteInputTest -minimize_crash=1 not_minimal_crash -exact_artifact_path=exact_minimized_path 2>&1 | FileCheck %s --check-prefix=MIN1 -MIN1: Test unit written to exact_minimized_path -MIN1: Test unit written to exact_minimized_path -MIN1: INFO: The input is small enough, exiting -MIN1: CRASH_MIN: failed to minimize beyond exact_minimized_path (1 bytes), exiting diff --git a/gnu/llvm/lib/Fuzzer/test/trace-malloc.test b/gnu/llvm/lib/Fuzzer/test/trace-malloc.test index 25694cc2de5..c95147904d4 100644 --- a/gnu/llvm/lib/Fuzzer/test/trace-malloc.test +++ b/gnu/llvm/lib/Fuzzer/test/trace-malloc.test @@ -3,3 +3,8 @@ CHECK-DAG: MallocFreeTracer: STOP 0 0 (same) CHECK-DAG: MallocFreeTracer: STOP 0 1 (DIFFERENT) CHECK-DAG: MallocFreeTracer: STOP 1 0 (DIFFERENT) CHECK-DAG: MallocFreeTracer: STOP 1 1 (same) + +RUN: LLVMFuzzer-TraceMallocTest -seed=1 -trace_malloc=2 -runs=1000 2>&1 | FileCheck %s --check-prefix=TRACE2 +TRACE2-DAG: FREE[0] +TRACE2-DAG: MALLOC[0] +TRACE2-DAG: in LLVMFuzzerTestOneInput diff --git a/gnu/llvm/lib/Fuzzer/test/ulimit.test b/gnu/llvm/lib/Fuzzer/test/ulimit.test index c2faca13f72..a60636c351b 100644 --- a/gnu/llvm/lib/Fuzzer/test/ulimit.test +++ b/gnu/llvm/lib/Fuzzer/test/ulimit.test @@ -1,4 +1,2 @@ -REQUIRES: posix - RUN: ulimit -s 1000 RUN: LLVMFuzzer-SimpleTest diff --git a/gnu/llvm/lib/Fuzzer/test/value-profile-div.test b/gnu/llvm/lib/Fuzzer/test/value-profile-div.test index b966a891651..ba45e4129d3 100644 --- a/gnu/llvm/lib/Fuzzer/test/value-profile-div.test +++ b/gnu/llvm/lib/Fuzzer/test/value-profile-div.test @@ -1,3 +1,3 @@ -CHECK: AddressSanitizer: {{FPE|int-divide-by-zero}} +CHECK: AddressSanitizer: FPE RUN: not LLVMFuzzer-DivTest -seed=1 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s diff --git a/gnu/llvm/lib/Fuzzer/test/value-profile-mem.test b/gnu/llvm/lib/Fuzzer/test/value-profile-mem.test index 880b2692910..09d737dbe73 100644 --- a/gnu/llvm/lib/Fuzzer/test/value-profile-mem.test +++ b/gnu/llvm/lib/Fuzzer/test/value-profile-mem.test @@ -1,2 +1,2 @@ CHECK: BINGO -RUN: not LLVMFuzzer-SingleMemcmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s +RUN: not LLVMFuzzer-SingleMemcmpTest -seed=1 -use_cmp=0 -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s diff --git a/gnu/llvm/lib/Fuzzer/test/value-profile-strcmp.test b/gnu/llvm/lib/Fuzzer/test/value-profile-strcmp.test index 7f104759454..1e7ef9b45e9 100644 --- a/gnu/llvm/lib/Fuzzer/test/value-profile-strcmp.test +++ b/gnu/llvm/lib/Fuzzer/test/value-profile-strcmp.test @@ -1,2 +1,2 @@ CHECK: BINGO -RUN: not LLVMFuzzer-SingleStrcmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s +RUN: not LLVMFuzzer-SingleStrcmpTest -seed=1 -use_cmp=0 -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s diff --git a/gnu/llvm/lib/Fuzzer/test/value-profile-strncmp.test b/gnu/llvm/lib/Fuzzer/test/value-profile-strncmp.test index 84a74c4f0ad..650973180c0 100644 --- a/gnu/llvm/lib/Fuzzer/test/value-profile-strncmp.test +++ b/gnu/llvm/lib/Fuzzer/test/value-profile-strncmp.test @@ -1,2 +1,2 @@ CHECK: BINGO -RUN: not LLVMFuzzer-SingleStrncmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s +RUN: not LLVMFuzzer-SingleStrncmpTest -seed=1 -use_cmp=0 -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s diff --git a/gnu/llvm/lib/Target/AArch64/AArch64VectorByElementOpt.cpp b/gnu/llvm/lib/Target/AArch64/AArch64VectorByElementOpt.cpp index f53af2315ec..e3b1d7cea48 100644 --- a/gnu/llvm/lib/Target/AArch64/AArch64VectorByElementOpt.cpp +++ b/gnu/llvm/lib/Target/AArch64/AArch64VectorByElementOpt.cpp @@ -19,27 +19,13 @@ // is rewritten into // dup v3.4s, v2.s[1] // fmla v0.4s, v1.4s, v3.4s -// //===----------------------------------------------------------------------===// #include "AArch64InstrInfo.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/TargetSchedule.h" -#include "llvm/MC/MCInstrDesc.h" -#include "llvm/MC/MCSchedule.h" -#include "llvm/Pass.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" -#include <map> using namespace llvm; @@ -55,15 +41,14 @@ namespace { struct AArch64VectorByElementOpt : public MachineFunctionPass { static char ID; + AArch64VectorByElementOpt() : MachineFunctionPass(ID) { + initializeAArch64VectorByElementOptPass(*PassRegistry::getPassRegistry()); + } const TargetInstrInfo *TII; MachineRegisterInfo *MRI; TargetSchedModel SchedModel; - AArch64VectorByElementOpt() : MachineFunctionPass(ID) { - initializeAArch64VectorByElementOptPass(*PassRegistry::getPassRegistry()); - } - /// Based only on latency of instructions, determine if it is cost efficient /// to replace the instruction InstDesc by the two instructions InstDescRep1 /// and InstDescRep2. @@ -105,10 +90,8 @@ struct AArch64VectorByElementOpt : public MachineFunctionPass { return AARCH64_VECTOR_BY_ELEMENT_OPT_NAME; } }; - char AArch64VectorByElementOpt::ID = 0; - -} // end anonymous namespace +} // namespace INITIALIZE_PASS(AArch64VectorByElementOpt, "aarch64-vectorbyelement-opt", AARCH64_VECTOR_BY_ELEMENT_OPT_NAME, false, false) diff --git a/gnu/llvm/lib/Target/AVR/AVRInstrumentFunctions.cpp b/gnu/llvm/lib/Target/AVR/AVRInstrumentFunctions.cpp index e7fca74e170..5553dc2da31 100644 --- a/gnu/llvm/lib/Target/AVR/AVRInstrumentFunctions.cpp +++ b/gnu/llvm/lib/Target/AVR/AVRInstrumentFunctions.cpp @@ -96,7 +96,7 @@ static void BuildSignatureCall(StringRef SymName, BasicBlock &BB, Function &F) { Value *FunctionName = CreateStringPtr(BB, F.getName()); Value *Args[] = {FunctionName, - ConstantInt::get(I16, F.arg_size())}; + ConstantInt::get(I16, F.getArgumentList().size())}; CallInst::Create(Fn, Args, "", &BB); } diff --git a/gnu/llvm/tools/lld/ELF/Memory.h b/gnu/llvm/tools/lld/ELF/Memory.h index 4000f2f9f1c..e5a04ed1e5a 100644 --- a/gnu/llvm/tools/lld/ELF/Memory.h +++ b/gnu/llvm/tools/lld/ELF/Memory.h @@ -61,7 +61,7 @@ inline void freeArena() { Alloc->reset(); BAlloc.Reset(); } -} // namespace elf -} // namespace lld +} +} #endif diff --git a/gnu/llvm/tools/lld/ELF/Threads.h b/gnu/llvm/tools/lld/ELF/Threads.h index 9feb8683976..c03e15253e1 100644 --- a/gnu/llvm/tools/lld/ELF/Threads.h +++ b/gnu/llvm/tools/lld/ELF/Threads.h @@ -15,7 +15,7 @@ // // That said, we don't want to do "too clever" things using threads. // Complex multi-threaded algorithms are sometimes extremely hard to -// reason about and can easily mess up the entire design. +// justify the correctness and can easily mess up the entire design. // // Fortunately, when a linker links large programs (when the link time is // most critical), it spends most of the time to work on massive number of @@ -34,7 +34,7 @@ // instead of std::for_each (or a plain for loop). Because tasks are // completely independent from each other, we can run them in parallel // without any coordination between them. That's very easy to understand -// and reason about. +// and justify. // // For the cases such as the latter, we can use parallel algorithms to // deal with massive data. We have to write code for a tailored algorithm @@ -61,28 +61,30 @@ #include "Config.h" -#include "llvm/Support/Parallel.h" +#include "lld/Core/Parallel.h" +#include <algorithm> #include <functional> namespace lld { namespace elf { template <class IterTy, class FuncTy> -void parallelForEach(IterTy Begin, IterTy End, FuncTy Fn) { +void forEach(IterTy Begin, IterTy End, FuncTy Fn) { if (Config->Threads) - for_each(llvm::parallel::par, Begin, End, Fn); + parallel_for_each(Begin, End, Fn); else - for_each(llvm::parallel::seq, Begin, End, Fn); + std::for_each(Begin, End, Fn); } -inline void parallelForEachN(size_t Begin, size_t End, - std::function<void(size_t)> Fn) { - if (Config->Threads) - for_each_n(llvm::parallel::par, Begin, End, Fn); - else - for_each_n(llvm::parallel::seq, Begin, End, Fn); +inline void forLoop(size_t Begin, size_t End, std::function<void(size_t)> Fn) { + if (Config->Threads) { + parallel_for(Begin, End, Fn); + } else { + for (size_t I = Begin; I < End; ++I) + Fn(I); + } +} +} } -} // namespace elf -} // namespace lld #endif diff --git a/gnu/llvm/unittests/ADT/ReverseIterationTest.cpp b/gnu/llvm/unittests/ADT/ReverseIterationTest.cpp index 1e2dedf083f..a1fd3b26d4e 100644 --- a/gnu/llvm/unittests/ADT/ReverseIterationTest.cpp +++ b/gnu/llvm/unittests/ADT/ReverseIterationTest.cpp @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/SmallPtrSet.h" #include "gtest/gtest.h" +#include "llvm/ADT/SmallPtrSet.h" #if LLVM_ENABLE_ABI_BREAKING_CHECKS using namespace llvm; diff --git a/gnu/llvm/unittests/DebugInfo/PDB/MSFBuilderTest.cpp b/gnu/llvm/unittests/DebugInfo/PDB/MSFBuilderTest.cpp index 23a15d14f75..5f2f0c271e9 100644 --- a/gnu/llvm/unittests/DebugInfo/PDB/MSFBuilderTest.cpp +++ b/gnu/llvm/unittests/DebugInfo/PDB/MSFBuilderTest.cpp @@ -7,9 +7,10 @@ // //===----------------------------------------------------------------------===// +#include "ErrorChecking.h" + #include "llvm/DebugInfo/MSF/MSFBuilder.h" #include "llvm/DebugInfo/MSF/MSFCommon.h" -#include "llvm/Testing/Support/Error.h" #include "gtest/gtest.h" @@ -45,7 +46,7 @@ TEST_F(MSFBuilderTest, ValidateSuperBlockAccept) { SuperBlock SB; initializeSuperBlock(SB); - EXPECT_THAT_ERROR(msf::validateSuperBlock(SB), Succeeded()); + EXPECT_NO_ERROR(msf::validateSuperBlock(SB)); } TEST_F(MSFBuilderTest, ValidateSuperBlockReject) { @@ -55,24 +56,24 @@ TEST_F(MSFBuilderTest, ValidateSuperBlockReject) { // Mismatched magic SB.MagicBytes[0] = 8; - EXPECT_THAT_ERROR(msf::validateSuperBlock(SB), Failed()); + EXPECT_ERROR(msf::validateSuperBlock(SB)); initializeSimpleSuperBlock(SB); // Block 0 is reserved for super block, can't be occupied by the block map SB.BlockMapAddr = 0; - EXPECT_THAT_ERROR(msf::validateSuperBlock(SB), Failed()); + EXPECT_ERROR(msf::validateSuperBlock(SB)); initializeSimpleSuperBlock(SB); // Block sizes have to be powers of 2. SB.BlockSize = 3120; - EXPECT_THAT_ERROR(msf::validateSuperBlock(SB), Failed()); + EXPECT_ERROR(msf::validateSuperBlock(SB)); initializeSimpleSuperBlock(SB); // The directory itself has a maximum size. SB.NumDirectoryBytes = SB.BlockSize * SB.BlockSize / 4; - EXPECT_THAT_ERROR(msf::validateSuperBlock(SB), Succeeded()); + EXPECT_NO_ERROR(msf::validateSuperBlock(SB)); SB.NumDirectoryBytes = SB.NumDirectoryBytes + 4; - EXPECT_THAT_ERROR(msf::validateSuperBlock(SB), Failed()); + EXPECT_ERROR(msf::validateSuperBlock(SB)); } TEST_F(MSFBuilderTest, TestUsedBlocksMarkedAsUsed) { @@ -85,11 +86,10 @@ TEST_F(MSFBuilderTest, TestUsedBlocksMarkedAsUsed) { // after the initialization. uint32_t NumBlocks = msf::getMinimumBlockCount() + Blocks.size() + 10; auto ExpectedMsf = MSFBuilder::create(Allocator, 4096, NumBlocks); - ASSERT_THAT_EXPECTED(ExpectedMsf, Succeeded()); + EXPECT_EXPECTED(ExpectedMsf); auto &Msf = *ExpectedMsf; - EXPECT_THAT_EXPECTED(Msf.addStream(Blocks.size() * 4096, Blocks), - Succeeded()); + EXPECT_EXPECTED(Msf.addStream(Blocks.size() * 4096, Blocks)); for (auto B : Blocks) { EXPECT_FALSE(Msf.isBlockFree(B)); @@ -106,28 +106,28 @@ TEST_F(MSFBuilderTest, TestAddStreamNoDirectoryBlockIncrease) { // tests the case where the directory *DOES NOT* grow large enough that it // crosses a Block boundary. auto ExpectedMsf = MSFBuilder::create(Allocator, 4096); - EXPECT_THAT_EXPECTED(ExpectedMsf, Succeeded()); + EXPECT_EXPECTED(ExpectedMsf); auto &Msf = *ExpectedMsf; auto ExpectedL1 = Msf.build(); - EXPECT_THAT_EXPECTED(ExpectedL1, Succeeded()); + EXPECT_EXPECTED(ExpectedL1); MSFLayout &L1 = *ExpectedL1; auto OldDirBlocks = L1.DirectoryBlocks; EXPECT_EQ(1U, OldDirBlocks.size()); auto ExpectedMsf2 = MSFBuilder::create(Allocator, 4096); - EXPECT_THAT_EXPECTED(ExpectedMsf2, Succeeded()); + EXPECT_EXPECTED(ExpectedMsf2); auto &Msf2 = *ExpectedMsf2; - EXPECT_THAT_EXPECTED(Msf2.addStream(4000), Succeeded()); + EXPECT_EXPECTED(Msf2.addStream(4000)); EXPECT_EQ(1U, Msf2.getNumStreams()); EXPECT_EQ(4000U, Msf2.getStreamSize(0)); auto Blocks = Msf2.getStreamBlocks(0); EXPECT_EQ(1U, Blocks.size()); auto ExpectedL2 = Msf2.build(); - EXPECT_THAT_EXPECTED(ExpectedL2, Succeeded()); + EXPECT_EXPECTED(ExpectedL2); MSFLayout &L2 = *ExpectedL2; auto NewDirBlocks = L2.DirectoryBlocks; EXPECT_EQ(1U, NewDirBlocks.size()); @@ -140,14 +140,13 @@ TEST_F(MSFBuilderTest, TestAddStreamWithDirectoryBlockIncrease) { // so many Blocks that need to be indexed in the directory that the directory // crosses a Block boundary. auto ExpectedMsf = MSFBuilder::create(Allocator, 4096); - EXPECT_THAT_EXPECTED(ExpectedMsf, Succeeded()); + EXPECT_EXPECTED(ExpectedMsf); auto &Msf = *ExpectedMsf; - EXPECT_THAT_EXPECTED(Msf.addStream(4096 * 4096 / sizeof(uint32_t)), - Succeeded()); + EXPECT_EXPECTED(Msf.addStream(4096 * 4096 / sizeof(uint32_t))); auto ExpectedL1 = Msf.build(); - EXPECT_THAT_EXPECTED(ExpectedL1, Succeeded()); + EXPECT_EXPECTED(ExpectedL1); MSFLayout &L1 = *ExpectedL1; auto DirBlocks = L1.DirectoryBlocks; EXPECT_EQ(2U, DirBlocks.size()); @@ -157,15 +156,15 @@ TEST_F(MSFBuilderTest, TestGrowStreamNoBlockIncrease) { // Test growing an existing stream by a value that does not affect the number // of blocks it occupies. auto ExpectedMsf = MSFBuilder::create(Allocator, 4096); - EXPECT_THAT_EXPECTED(ExpectedMsf, Succeeded()); + EXPECT_EXPECTED(ExpectedMsf); auto &Msf = *ExpectedMsf; - EXPECT_THAT_EXPECTED(Msf.addStream(1024), Succeeded()); + EXPECT_EXPECTED(Msf.addStream(1024)); EXPECT_EQ(1024U, Msf.getStreamSize(0)); auto OldStreamBlocks = Msf.getStreamBlocks(0); EXPECT_EQ(1U, OldStreamBlocks.size()); - EXPECT_THAT_ERROR(Msf.setStreamSize(0, 2048), Succeeded()); + EXPECT_NO_ERROR(Msf.setStreamSize(0, 2048)); EXPECT_EQ(2048U, Msf.getStreamSize(0)); auto NewStreamBlocks = Msf.getStreamBlocks(0); EXPECT_EQ(1U, NewStreamBlocks.size()); @@ -179,15 +178,15 @@ TEST_F(MSFBuilderTest, TestGrowStreamWithBlockIncrease) { // stream's // block list. auto ExpectedMsf = MSFBuilder::create(Allocator, 4096); - EXPECT_THAT_EXPECTED(ExpectedMsf, Succeeded()); + EXPECT_EXPECTED(ExpectedMsf); auto &Msf = *ExpectedMsf; - EXPECT_THAT_EXPECTED(Msf.addStream(2048), Succeeded()); + EXPECT_EXPECTED(Msf.addStream(2048)); EXPECT_EQ(2048U, Msf.getStreamSize(0)); std::vector<uint32_t> OldStreamBlocks = Msf.getStreamBlocks(0); EXPECT_EQ(1U, OldStreamBlocks.size()); - EXPECT_THAT_ERROR(Msf.setStreamSize(0, 6144), Succeeded()); + EXPECT_NO_ERROR(Msf.setStreamSize(0, 6144)); EXPECT_EQ(6144U, Msf.getStreamSize(0)); std::vector<uint32_t> NewStreamBlocks = Msf.getStreamBlocks(0); EXPECT_EQ(2U, NewStreamBlocks.size()); @@ -200,15 +199,15 @@ TEST_F(MSFBuilderTest, TestShrinkStreamNoBlockDecrease) { // Test that shrinking an existing stream by a value that does not affect the // number of Blocks it occupies makes no changes to stream's block list. auto ExpectedMsf = MSFBuilder::create(Allocator, 4096); - EXPECT_THAT_EXPECTED(ExpectedMsf, Succeeded()); + EXPECT_EXPECTED(ExpectedMsf); auto &Msf = *ExpectedMsf; - EXPECT_THAT_EXPECTED(Msf.addStream(2048), Succeeded()); + EXPECT_EXPECTED(Msf.addStream(2048)); EXPECT_EQ(2048U, Msf.getStreamSize(0)); std::vector<uint32_t> OldStreamBlocks = Msf.getStreamBlocks(0); EXPECT_EQ(1U, OldStreamBlocks.size()); - EXPECT_THAT_ERROR(Msf.setStreamSize(0, 1024), Succeeded()); + EXPECT_NO_ERROR(Msf.setStreamSize(0, 1024)); EXPECT_EQ(1024U, Msf.getStreamSize(0)); std::vector<uint32_t> NewStreamBlocks = Msf.getStreamBlocks(0); EXPECT_EQ(1U, NewStreamBlocks.size()); @@ -221,15 +220,15 @@ TEST_F(MSFBuilderTest, TestShrinkStreamWithBlockDecrease) { // causes the need to deallocate new Blocks to the stream correctly updates // the stream's block list. auto ExpectedMsf = MSFBuilder::create(Allocator, 4096); - EXPECT_THAT_EXPECTED(ExpectedMsf, Succeeded()); + EXPECT_EXPECTED(ExpectedMsf); auto &Msf = *ExpectedMsf; - EXPECT_THAT_EXPECTED(Msf.addStream(6144), Succeeded()); + EXPECT_EXPECTED(Msf.addStream(6144)); EXPECT_EQ(6144U, Msf.getStreamSize(0)); std::vector<uint32_t> OldStreamBlocks = Msf.getStreamBlocks(0); EXPECT_EQ(2U, OldStreamBlocks.size()); - EXPECT_THAT_ERROR(Msf.setStreamSize(0, 2048), Succeeded()); + EXPECT_NO_ERROR(Msf.setStreamSize(0, 2048)); EXPECT_EQ(2048U, Msf.getStreamSize(0)); std::vector<uint32_t> NewStreamBlocks = Msf.getStreamBlocks(0); EXPECT_EQ(1U, NewStreamBlocks.size()); @@ -241,20 +240,20 @@ TEST_F(MSFBuilderTest, TestRejectReusedStreamBlock) { // Test that attempting to add a stream and assigning a block that is already // in use by another stream fails. auto ExpectedMsf = MSFBuilder::create(Allocator, 4096); - EXPECT_THAT_EXPECTED(ExpectedMsf, Succeeded()); + EXPECT_EXPECTED(ExpectedMsf); auto &Msf = *ExpectedMsf; - EXPECT_THAT_EXPECTED(Msf.addStream(6144), Succeeded()); + EXPECT_EXPECTED(Msf.addStream(6144)); std::vector<uint32_t> Blocks = {2, 3}; - EXPECT_THAT_EXPECTED(Msf.addStream(6144, Blocks), Failed()); + EXPECT_UNEXPECTED(Msf.addStream(6144, Blocks)); } TEST_F(MSFBuilderTest, TestBlockCountsWhenAddingStreams) { // Test that when adding multiple streams, the number of used and free Blocks // allocated to the MSF file are as expected. auto ExpectedMsf = MSFBuilder::create(Allocator, 4096); - EXPECT_THAT_EXPECTED(ExpectedMsf, Succeeded()); + EXPECT_EXPECTED(ExpectedMsf); auto &Msf = *ExpectedMsf; // one for the super block, one for the directory block map @@ -264,7 +263,7 @@ TEST_F(MSFBuilderTest, TestBlockCountsWhenAddingStreams) { const uint32_t StreamSizes[] = {4000, 6193, 189723}; for (int I = 0; I < 3; ++I) { - EXPECT_THAT_EXPECTED(Msf.addStream(StreamSizes[I]), Succeeded()); + EXPECT_EXPECTED(Msf.addStream(StreamSizes[I])); NumUsedBlocks += bytesToBlocks(StreamSizes[I], 4096); EXPECT_EQ(NumUsedBlocks, Msf.getNumUsedBlocks()); EXPECT_EQ(0U, Msf.getNumFreeBlocks()); @@ -275,19 +274,19 @@ TEST_F(MSFBuilderTest, BuildMsfLayout) { // Test that we can generate an MSFLayout structure from a valid layout // specification. auto ExpectedMsf = MSFBuilder::create(Allocator, 4096); - EXPECT_THAT_EXPECTED(ExpectedMsf, Succeeded()); + EXPECT_EXPECTED(ExpectedMsf); auto &Msf = *ExpectedMsf; const uint32_t StreamSizes[] = {4000, 6193, 189723}; uint32_t ExpectedNumBlocks = msf::getMinimumBlockCount(); for (int I = 0; I < 3; ++I) { - EXPECT_THAT_EXPECTED(Msf.addStream(StreamSizes[I]), Succeeded()); + EXPECT_EXPECTED(Msf.addStream(StreamSizes[I])); ExpectedNumBlocks += bytesToBlocks(StreamSizes[I], 4096); } ++ExpectedNumBlocks; // The directory itself should use 1 block auto ExpectedLayout = Msf.build(); - EXPECT_THAT_EXPECTED(ExpectedLayout, Succeeded()); + EXPECT_EXPECTED(ExpectedLayout); MSFLayout &L = *ExpectedLayout; EXPECT_EQ(4096U, L.SB->BlockSize); EXPECT_EQ(ExpectedNumBlocks, L.SB->NumBlocks); @@ -306,15 +305,15 @@ TEST_F(MSFBuilderTest, BuildMsfLayout) { TEST_F(MSFBuilderTest, UseDirectoryBlockHint) { Expected<MSFBuilder> ExpectedMsf = MSFBuilder::create( Allocator, 4096, msf::getMinimumBlockCount() + 1, false); - EXPECT_THAT_EXPECTED(ExpectedMsf, Succeeded()); + EXPECT_EXPECTED(ExpectedMsf); auto &Msf = *ExpectedMsf; uint32_t B = msf::getFirstUnreservedBlock(); - EXPECT_THAT_ERROR(Msf.setDirectoryBlocksHint({B + 1}), Succeeded()); - EXPECT_THAT_EXPECTED(Msf.addStream(2048, {B + 2}), Succeeded()); + EXPECT_NO_ERROR(Msf.setDirectoryBlocksHint({B + 1})); + EXPECT_EXPECTED(Msf.addStream(2048, {B + 2})); auto ExpectedLayout = Msf.build(); - EXPECT_THAT_EXPECTED(ExpectedLayout, Succeeded()); + EXPECT_EXPECTED(ExpectedLayout); MSFLayout &L = *ExpectedLayout; EXPECT_EQ(msf::getMinimumBlockCount() + 2, L.SB->NumBlocks); EXPECT_EQ(1U, L.DirectoryBlocks.size()); @@ -327,16 +326,16 @@ TEST_F(MSFBuilderTest, UseDirectoryBlockHint) { TEST_F(MSFBuilderTest, DirectoryBlockHintInsufficient) { Expected<MSFBuilder> ExpectedMsf = MSFBuilder::create(Allocator, 4096, msf::getMinimumBlockCount() + 2); - EXPECT_THAT_EXPECTED(ExpectedMsf, Succeeded()); + EXPECT_EXPECTED(ExpectedMsf); auto &Msf = *ExpectedMsf; uint32_t B = msf::getFirstUnreservedBlock(); - EXPECT_THAT_ERROR(Msf.setDirectoryBlocksHint({B + 1}), Succeeded()); + EXPECT_NO_ERROR(Msf.setDirectoryBlocksHint({B + 1})); uint32_t Size = 4096 * 4096 / 4; - EXPECT_THAT_EXPECTED(Msf.addStream(Size), Succeeded()); + EXPECT_EXPECTED(Msf.addStream(Size)); auto ExpectedLayout = Msf.build(); - EXPECT_THAT_EXPECTED(ExpectedLayout, Succeeded()); + EXPECT_EXPECTED(ExpectedLayout); MSFLayout &L = *ExpectedLayout; EXPECT_EQ(2U, L.DirectoryBlocks.size()); EXPECT_EQ(B + 1, L.DirectoryBlocks[0]); @@ -345,16 +344,16 @@ TEST_F(MSFBuilderTest, DirectoryBlockHintInsufficient) { TEST_F(MSFBuilderTest, DirectoryBlockHintOverestimated) { Expected<MSFBuilder> ExpectedMsf = MSFBuilder::create(Allocator, 4096, msf::getMinimumBlockCount() + 2); - EXPECT_THAT_EXPECTED(ExpectedMsf, Succeeded()); + EXPECT_EXPECTED(ExpectedMsf); auto &Msf = *ExpectedMsf; uint32_t B = msf::getFirstUnreservedBlock(); - EXPECT_THAT_ERROR(Msf.setDirectoryBlocksHint({B + 1, B + 2}), Succeeded()); + EXPECT_NO_ERROR(Msf.setDirectoryBlocksHint({B + 1, B + 2})); - ASSERT_THAT_EXPECTED(Msf.addStream(2048), Succeeded()); + EXPECT_EXPECTED(Msf.addStream(2048)); auto ExpectedLayout = Msf.build(); - ASSERT_THAT_EXPECTED(ExpectedLayout, Succeeded()); + EXPECT_EXPECTED(ExpectedLayout); MSFLayout &L = *ExpectedLayout; EXPECT_EQ(1U, L.DirectoryBlocks.size()); EXPECT_EQ(B + 1, L.DirectoryBlocks[0]); |