LLVM  4.0.0
FuzzerIO.cpp
Go to the documentation of this file.
1 //===- FuzzerIO.cpp - IO utils. -------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // IO functions.
10 //===----------------------------------------------------------------------===//
11 
12 #include "FuzzerIO.h"
13 #include "FuzzerDefs.h"
14 #include "FuzzerExtFunctions.h"
15 #include <algorithm>
16 #include <cstdarg>
17 #include <fstream>
18 #include <iterator>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 
22 namespace fuzzer {
23 
24 static FILE *OutputFile = stderr;
25 
26 long GetEpoch(const std::string &Path) {
27  struct stat St;
28  if (stat(Path.c_str(), &St))
29  return 0; // Can't stat, be conservative.
30  return St.st_mtime;
31 }
32 
33 Unit FileToVector(const std::string &Path, size_t MaxSize, bool ExitOnError) {
34  std::ifstream T(Path);
35  if (ExitOnError && !T) {
36  Printf("No such directory: %s; exiting\n", Path.c_str());
37  exit(1);
38  }
39 
40  T.seekg(0, T.end);
41  size_t FileLen = T.tellg();
42  if (MaxSize)
43  FileLen = std::min(FileLen, MaxSize);
44 
45  T.seekg(0, T.beg);
46  Unit Res(FileLen);
47  T.read(reinterpret_cast<char *>(Res.data()), FileLen);
48  return Res;
49 }
50 
51 std::string FileToString(const std::string &Path) {
52  std::ifstream T(Path);
53  return std::string((std::istreambuf_iterator<char>(T)),
54  std::istreambuf_iterator<char>());
55 }
56 
57 void CopyFileToErr(const std::string &Path) {
58  Printf("%s", FileToString(Path).c_str());
59 }
60 
61 void WriteToFile(const Unit &U, const std::string &Path) {
62  // Use raw C interface because this function may be called from a sig handler.
63  FILE *Out = fopen(Path.c_str(), "w");
64  if (!Out) return;
65  fwrite(U.data(), sizeof(U[0]), U.size(), Out);
66  fclose(Out);
67 }
68 
69 void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V,
70  long *Epoch, size_t MaxSize, bool ExitOnError) {
71  long E = Epoch ? *Epoch : 0;
72  std::vector<std::string> Files;
73  ListFilesInDirRecursive(Path, Epoch, &Files, /*TopDir*/true);
74  size_t NumLoaded = 0;
75  for (size_t i = 0; i < Files.size(); i++) {
76  auto &X = Files[i];
77  if (Epoch && GetEpoch(X) < E) continue;
78  NumLoaded++;
79  if ((NumLoaded & (NumLoaded - 1)) == 0 && NumLoaded >= 1024)
80  Printf("Loaded %zd/%zd files from %s\n", NumLoaded, Files.size(), Path);
81  auto S = FileToVector(X, MaxSize, ExitOnError);
82  if (!S.empty())
83  V->push_back(S);
84  }
85 }
86 
87 std::string DirPlusFile(const std::string &DirPath,
88  const std::string &FileName) {
89  return DirPath + GetSeparator() + FileName;
90 }
91 
93  int OutputFd = DuplicateFile(2);
94  if (OutputFd > 0) {
95  FILE *NewOutputFile = OpenFile(OutputFd, "w");
96  if (NewOutputFile) {
97  OutputFile = NewOutputFile;
98  if (EF->__sanitizer_set_report_fd)
99  EF->__sanitizer_set_report_fd(reinterpret_cast<void *>(OutputFd));
100  CloseFile(2);
101  }
102  }
103 }
104 
105 void CloseStdout() {
106  CloseFile(1);
107 }
108 
109 void Printf(const char *Fmt, ...) {
110  va_list ap;
111  va_start(ap, Fmt);
112  vfprintf(OutputFile, Fmt, ap);
113  va_end(ap);
114  fflush(OutputFile);
115 }
116 
117 } // namespace fuzzer
int CloseFile(int Fd)
size_t i
int DuplicateFile(int Fd)
static FILE * OutputFile
Definition: FuzzerIO.cpp:24
void ListFilesInDirRecursive(const std::string &Dir, long *Epoch, std::vector< std::string > *V, bool TopDir)
ExternalFunctions * EF
void CloseStdout()
Definition: FuzzerIO.cpp:105
void DupAndCloseStderr()
Definition: FuzzerIO.cpp:92
std::string FileToString(const std::string &Path)
Definition: FuzzerIO.cpp:51
void ReadDirToVectorOfUnits(const char *Path, std::vector< Unit > *V, long *Epoch, size_t MaxSize, bool ExitOnError)
Definition: FuzzerIO.cpp:69
#define T
long GetEpoch(const std::string &Path)
Definition: FuzzerIO.cpp:26
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
void Printf(const char *Fmt,...)
Definition: FuzzerIO.cpp:109
FILE * OpenFile(int Fd, const char *Mode)
std::string DirPlusFile(const std::string &DirPath, const std::string &FileName)
Definition: FuzzerIO.cpp:87
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
void CopyFileToErr(const std::string &Path)
Definition: FuzzerIO.cpp:57
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
void WriteToFile(const Unit &U, const std::string &Path)
Definition: FuzzerIO.cpp:61
Unit FileToVector(const std::string &Path, size_t MaxSize, bool ExitOnError)
Definition: FuzzerIO.cpp:33
std::vector< uint8_t > Unit
Definition: FuzzerDefs.h:71
char GetSeparator()