@@ -250,6 +250,28 @@ static void WorkerThread(const Command &BaseCmd, std::atomic<unsigned> *Counter,
250
250
}
251
251
}
252
252
253
+ static void ValidateDirectoryExists (const std::string &Path,
254
+ bool CreateDirectory) {
255
+ if (Path.empty ()) {
256
+ Printf (" ERROR: Provided directory path is an empty string\n " );
257
+ exit (1 );
258
+ }
259
+
260
+ if (IsDirectory (Path))
261
+ return ;
262
+
263
+ if (CreateDirectory) {
264
+ if (!MkDirRecursive (Path)) {
265
+ Printf (" ERROR: Failed to create directory \" %s\"\n " , Path.c_str ());
266
+ exit (1 );
267
+ }
268
+ return ;
269
+ }
270
+
271
+ Printf (" ERROR: The required directory \" %s\" does not exist\n " , Path.c_str ());
272
+ exit (1 );
273
+ }
274
+
253
275
std::string CloneArgsWithoutX (const Vector<std::string> &Args,
254
276
const char *X1, const char *X2) {
255
277
std::string Cmd;
@@ -299,7 +321,12 @@ int RunOneTest(Fuzzer *F, const char *InputFilePath, size_t MaxLen) {
299
321
if (MaxLen && MaxLen < U.size ())
300
322
U.resize (MaxLen);
301
323
F->ExecuteCallback (U.data (), U.size ());
302
- F->TryDetectingAMemoryLeak (U.data (), U.size (), true );
324
+ if (Flags.print_full_coverage ) {
325
+ // Leak detection is not needed when collecting full coverage data.
326
+ F->TPCUpdateObservedPCs ();
327
+ } else {
328
+ F->TryDetectingAMemoryLeak (U.data (), U.size (), true );
329
+ }
303
330
return 0 ;
304
331
}
305
332
@@ -649,6 +676,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
649
676
Options.Verbosity = Flags.verbosity ;
650
677
Options.MaxLen = Flags.max_len ;
651
678
Options.LenControl = Flags.len_control ;
679
+ Options.KeepSeed = Flags.keep_seed ;
652
680
Options.UnitTimeoutSec = Flags.timeout ;
653
681
Options.ErrorExitCode = Flags.error_exitcode ;
654
682
Options.TimeoutExitCode = Flags.timeout_exitcode ;
@@ -657,6 +685,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
657
685
Options.IgnoreCrashes = Flags.ignore_crashes ;
658
686
Options.MaxTotalTimeSec = Flags.max_total_time ;
659
687
Options.DoCrossOver = Flags.cross_over ;
688
+ Options.CrossOverUniformDist = Flags.cross_over_uniform_dist ;
660
689
Options.MutateDepth = Flags.mutate_depth ;
661
690
Options.ReduceDepth = Flags.reduce_depth ;
662
691
Options.UseCounters = Flags.use_counters ;
@@ -678,13 +707,33 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
678
707
Options.MallocLimitMb = Options.RssLimitMb ;
679
708
if (Flags.runs >= 0 )
680
709
Options.MaxNumberOfRuns = Flags.runs ;
681
- if (!Inputs->empty () && !Flags.minimize_crash_internal_step )
682
- Options.OutputCorpus = (*Inputs)[0 ];
710
+ if (!Inputs->empty () && !Flags.minimize_crash_internal_step ) {
711
+ // Ensure output corpus assumed to be the first arbitrary argument input
712
+ // is not a path to an existing file.
713
+ std::string OutputCorpusDir = (*Inputs)[0 ];
714
+ if (!IsFile (OutputCorpusDir)) {
715
+ Options.OutputCorpus = OutputCorpusDir;
716
+ ValidateDirectoryExists (Options.OutputCorpus , Flags.create_missing_dirs );
717
+ }
718
+ }
683
719
Options.ReportSlowUnits = Flags.report_slow_units ;
684
- if (Flags.artifact_prefix )
720
+ if (Flags.artifact_prefix ) {
685
721
Options.ArtifactPrefix = Flags.artifact_prefix ;
686
- if (Flags.exact_artifact_path )
722
+
723
+ // Since the prefix could be a full path to a file name prefix, assume
724
+ // that if the path ends with the platform's separator that a directory
725
+ // is desired
726
+ std::string ArtifactPathDir = Options.ArtifactPrefix ;
727
+ if (!IsSeparator (ArtifactPathDir[ArtifactPathDir.length () - 1 ])) {
728
+ ArtifactPathDir = DirName (ArtifactPathDir);
729
+ }
730
+ ValidateDirectoryExists (ArtifactPathDir, Flags.create_missing_dirs );
731
+ }
732
+ if (Flags.exact_artifact_path ) {
687
733
Options.ExactArtifactPath = Flags.exact_artifact_path ;
734
+ ValidateDirectoryExists (DirName (Options.ExactArtifactPath ),
735
+ Flags.create_missing_dirs );
736
+ }
688
737
Vector<Unit> Dictionary;
689
738
if (Flags.dict )
690
739
if (!ParseDictionaryFile (FileToString (Flags.dict ), &Dictionary))
@@ -699,6 +748,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
699
748
Options.PrintFinalStats = Flags.print_final_stats ;
700
749
Options.PrintCorpusStats = Flags.print_corpus_stats ;
701
750
Options.PrintCoverage = Flags.print_coverage ;
751
+ Options.PrintFullCoverage = Flags.print_full_coverage ;
702
752
if (Flags.exit_on_src_pos )
703
753
Options.ExitOnSrcPos = Flags.exit_on_src_pos ;
704
754
if (Flags.exit_on_item )
@@ -707,8 +757,12 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
707
757
Options.FocusFunction = Flags.focus_function ;
708
758
if (Flags.data_flow_trace )
709
759
Options.DataFlowTrace = Flags.data_flow_trace ;
710
- if (Flags.features_dir )
760
+ if (Flags.features_dir ) {
711
761
Options.FeaturesDir = Flags.features_dir ;
762
+ ValidateDirectoryExists (Options.FeaturesDir , Flags.create_missing_dirs );
763
+ }
764
+ if (Flags.mutation_graph_file )
765
+ Options.MutationGraphFile = Flags.mutation_graph_file ;
712
766
if (Flags.collect_data_flow )
713
767
Options.CollectDataFlow = Flags.collect_data_flow ;
714
768
if (Flags.stop_file )
@@ -718,21 +772,19 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
718
772
(size_t )Flags.entropic_feature_frequency_threshold ;
719
773
Options.EntropicNumberOfRarestFeatures =
720
774
(size_t )Flags.entropic_number_of_rarest_features ;
721
- if (Options.Entropic ) {
722
- if (!Options.FocusFunction .empty ()) {
723
- Printf (" ERROR: The parameters `--entropic` and `--focus_function` cannot "
724
- " be used together.\n " );
725
- exit (1 );
726
- }
775
+ Options.EntropicScalePerExecTime = Flags.entropic_scale_per_exec_time ;
776
+ if (!Options.FocusFunction .empty ())
777
+ Options.Entropic = false ; // FocusFunction overrides entropic scheduling.
778
+ if (Options.Entropic )
727
779
Printf (" INFO: Running with entropic power schedule (0x%X, %d).\n " ,
728
780
Options.EntropicFeatureFrequencyThreshold ,
729
781
Options.EntropicNumberOfRarestFeatures );
730
- }
731
782
struct EntropicOptions Entropic;
732
783
Entropic.Enabled = Options.Entropic ;
733
784
Entropic.FeatureFrequencyThreshold =
734
785
Options.EntropicFeatureFrequencyThreshold ;
735
786
Entropic.NumberOfRarestFeatures = Options.EntropicNumberOfRarestFeatures ;
787
+ Entropic.ScalePerExecTime = Options.EntropicScalePerExecTime ;
736
788
737
789
unsigned Seed = Flags.seed ;
738
790
// Initialize Seed.
@@ -767,6 +819,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
767
819
#endif // LIBFUZZER_EMSCRIPTEN
768
820
769
821
Options.HandleAbrt = Flags.handle_abrt ;
822
+ Options.HandleAlrm = !Flags.minimize_crash ;
770
823
Options.HandleBus = Flags.handle_bus ;
771
824
Options.HandleFpe = Flags.handle_fpe ;
772
825
Options.HandleIll = Flags.handle_ill ;
@@ -776,6 +829,8 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
776
829
Options.HandleXfsz = Flags.handle_xfsz ;
777
830
Options.HandleUsr1 = Flags.handle_usr1 ;
778
831
Options.HandleUsr2 = Flags.handle_usr2 ;
832
+ Options.HandleWinExcept = Flags.handle_winexcept ;
833
+
779
834
SetSignalHandler (Options);
780
835
781
836
std::atexit (Fuzzer::StaticExitCallback);
@@ -858,6 +913,12 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
858
913
exit (0 ); // Don't let F destroy itself.
859
914
}
860
915
916
+ extern " C" ATTRIBUTE_INTERFACE int
917
+ LLVMFuzzerRunDriver (int *argc, char ***argv,
918
+ int (*UserCb)(const uint8_t *Data, size_t Size)) {
919
+ return FuzzerDriver (argc, argv, UserCb);
920
+ }
921
+
861
922
// Storage for global ExternalFunctions object.
862
923
ExternalFunctions *EF = nullptr ;
863
924
0 commit comments