This change introduces libMutagen/libclang_rt.mutagen.a as a subset of libFuzzer/libclang_rt.fuzzer.a. This library contains only the fuzzing strategies used by libFuzzer to produce new test inputs from provided inputs, dictionaries, and SanitizerCoverage feedback.
Most of this change is simply moving sections of code to one side or the other of the library boundary. The only meaningful new code is:
- The Mutagen.h interface and its implementation in Mutagen.cpp.
- The following methods in MutagenDispatcher.cpp:
- UseCmp
- UseMemmem
- SetCustomMutator
- SetCustomCrossOver
- LateInitialize (similar to the MutationDispatcher's original constructor)
- Mutate_AddWordFromTORC (uses callbacks instead of accessing TPC directly)
- StartMutationSequence
- MutationSequence
- DictionaryEntrySequence
- RecommendDictionary
- RecommendDictionaryEntry
- FuzzerMutate.cpp (which now justs sets callbacks and handles printing)
- MutagenUnittest.cpp (which adds tests of Mutagen.h)
A note on performance: This change was tested with a 100 passes of test/fuzzer/LargeTest.cpp with 1000 runs per pass, both with and without the change. The running time distribution was qualitatively similar both with and without the change, and the average difference was within 30 microseconds (2.240 ms/run vs 2.212 ms/run, respectively). Both times were much higher than observed with the fully optimized system clang (~0.38 ms/run), most likely due to the combination of CMake "dev mode" settings (e.g. CMAKE_BUILD_TYPE="Debug", LLVM_ENABLE_LTO=OFF, etc.). The difference between the two versions built similarly seems to be "in the noise" and suggests no meaningful performance degradation.
Why is ATTRIBUTE_NO_SANITIZE_ALL needed?
It can't hurt, I'm just curious. AFAIK we don't normally compile the libFuzzer code itself with sanitizers anymore.