endif()
add_library(LLVMFuzzerNoMainObjects OBJECT
FuzzerCrossOver.cpp
- FuzzerTraceState.cpp
FuzzerDriver.cpp
FuzzerExtFunctionsDlsym.cpp
FuzzerExtFunctionsWeak.cpp
FuzzerIO.cpp
+ FuzzerIOPosix.cpp
+ FuzzerIOWindows.cpp
FuzzerLoop.cpp
FuzzerMutate.cpp
FuzzerSHA1.cpp
FuzzerTracePC.cpp
+ FuzzerTraceState.cpp
FuzzerUtil.cpp
FuzzerUtilDarwin.cpp
FuzzerUtilLinux.cpp
#include "FuzzerIO.h"
#include "FuzzerDefs.h"
#include "FuzzerExtFunctions.h"
-#include <iterator>
+#include <algorithm>
+#include <cstdarg>
#include <fstream>
-#include <dirent.h>
+#include <iterator>
#include <sys/types.h>
#include <sys/stat.h>
-#include <unistd.h>
-#include <cstdarg>
-#include <cstdio>
namespace fuzzer {
static FILE *OutputFile = stderr;
-bool IsFile(const std::string &Path) {
- struct stat St;
- if (stat(Path.c_str(), &St))
- return false;
- return S_ISREG(St.st_mode);
-}
-
long GetEpoch(const std::string &Path) {
struct stat St;
if (stat(Path.c_str(), &St))
return St.st_mtime;
}
-static void ListFilesInDirRecursive(const std::string &Dir, long *Epoch,
- std::vector<std::string> *V, bool TopDir) {
- auto E = GetEpoch(Dir);
- if (Epoch)
- if (E && *Epoch >= E) return;
-
- DIR *D = opendir(Dir.c_str());
- if (!D) {
- Printf("No such directory: %s; exiting\n", Dir.c_str());
- exit(1);
- }
- while (auto E = readdir(D)) {
- std::string Path = DirPlusFile(Dir, E->d_name);
- if (E->d_type == DT_REG || E->d_type == DT_LNK)
- V->push_back(Path);
- else if (E->d_type == DT_DIR && *E->d_name != '.')
- ListFilesInDirRecursive(Path, Epoch, V, false);
- }
- closedir(D);
- if (Epoch && TopDir)
- *Epoch = E;
-}
-
Unit FileToVector(const std::string &Path, size_t MaxSize, bool ExitOnError) {
std::ifstream T(Path);
if (ExitOnError && !T) {
return Res;
}
-void DeleteFile(const std::string &Path) {
- unlink(Path.c_str());
-}
-
std::string FileToString(const std::string &Path) {
std::ifstream T(Path);
return std::string((std::istreambuf_iterator<char>(T)),
std::string DirPlusFile(const std::string &DirPath,
const std::string &FileName) {
- return DirPath + "/" + FileName;
+ return DirPath + GetSeparator() + FileName;
}
void DupAndCloseStderr() {
- int OutputFd = dup(2);
+ int OutputFd = DuplicateFile(2);
if (OutputFd > 0) {
- FILE *NewOutputFile = fdopen(OutputFd, "w");
+ FILE *NewOutputFile = OpenFile(OutputFd, "w");
if (NewOutputFile) {
OutputFile = NewOutputFile;
if (EF->__sanitizer_set_report_fd)
EF->__sanitizer_set_report_fd(reinterpret_cast<void *>(OutputFd));
- close(2);
+ CloseFile(2);
}
}
}
-void CloseStdout() { close(1); }
+void CloseStdout() {
+ CloseFile(1);
+}
void Printf(const char *Fmt, ...) {
va_list ap;
namespace fuzzer {
-bool IsFile(const std::string &Path);
-
long GetEpoch(const std::string &Path);
Unit FileToVector(const std::string &Path, size_t MaxSize = 0,
bool ExitOnError = true);
-void DeleteFile(const std::string &Path);
-
std::string FileToString(const std::string &Path);
void CopyFileToErr(const std::string &Path);
void Printf(const char *Fmt, ...);
+// Platform specific functions:
+bool IsFile(const std::string &Path);
+
+void ListFilesInDirRecursive(const std::string &Dir, long *Epoch,
+ std::vector<std::string> *V, bool TopDir);
+
+char GetSeparator();
+
+FILE* OpenFile(int Fd, const char *Mode);
+
+int CloseFile(int Fd);
+
+int DuplicateFile(int Fd);
+
+void DeleteFile(const std::string &Path);
+
} // namespace fuzzer
#endif // LLVM_FUZZER_IO_H
--- /dev/null
+//===- FuzzerIOPosix.cpp - IO utils for Posix. ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// IO functions implementation using Posix API.
+//===----------------------------------------------------------------------===//
+
+#include "FuzzerDefs.h"
+#if LIBFUZZER_POSIX
+#include "FuzzerExtFunctions.h"
+#include "FuzzerIO.h"
+#include <cstdarg>
+#include <cstdio>
+#include <dirent.h>
+#include <fstream>
+#include <iterator>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+namespace fuzzer {
+
+bool IsFile(const std::string &Path) {
+ struct stat St;
+ if (stat(Path.c_str(), &St))
+ return false;
+ return S_ISREG(St.st_mode);
+}
+
+void ListFilesInDirRecursive(const std::string &Dir, long *Epoch,
+ std::vector<std::string> *V, bool TopDir) {
+ auto E = GetEpoch(Dir);
+ if (Epoch)
+ if (E && *Epoch >= E) return;
+
+ DIR *D = opendir(Dir.c_str());
+ if (!D) {
+ Printf("No such directory: %s; exiting\n", Dir.c_str());
+ exit(1);
+ }
+ while (auto E = readdir(D)) {
+ std::string Path = DirPlusFile(Dir, E->d_name);
+ if (E->d_type == DT_REG || E->d_type == DT_LNK)
+ V->push_back(Path);
+ else if (E->d_type == DT_DIR && *E->d_name != '.')
+ ListFilesInDirRecursive(Path, Epoch, V, false);
+ }
+ closedir(D);
+ if (Epoch && TopDir)
+ *Epoch = E;
+}
+
+char GetSeparator() {
+ return '/';
+}
+
+FILE* OpenFile(int Fd, const char* Mode) {
+ return fdopen(Fd, Mode);
+}
+
+int CloseFile(int fd) {
+ return close(fd);
+}
+
+int DuplicateFile(int Fd) {
+ return dup(Fd);
+}
+
+void DeleteFile(const std::string &Path) {
+ unlink(Path.c_str());
+}
+
+} // namespace fuzzer
+#endif // LIBFUZZER_POSIX
--- /dev/null
+//===- FuzzerIOWindows.cpp - IO utils for Windows. ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// IO functions implementation for Windows.
+//===----------------------------------------------------------------------===//
+
+#include "FuzzerDefs.h"
+#if LIBFUZZER_WINDOWS
+#include "FuzzerExtFunctions.h"
+#include "FuzzerIO.h"
+#include <cstdarg>
+#include <cstdio>
+#include <fstream>
+#include <io.h>
+#include <iterator>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <windows.h>
+
+namespace fuzzer {
+
+static bool IsFile(const std::string &Path, const DWORD &FileAttributes) {
+
+ if (FileAttributes & FILE_ATTRIBUTE_NORMAL)
+ return true;
+
+ if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ return false;
+
+ HANDLE FileHandle(
+ CreateFileA(Path.c_str(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, 0));
+
+ if (FileHandle == INVALID_HANDLE_VALUE) {
+ Printf("CreateFileA() failed for \"%s\" (Error code: %lu).\n", Path.c_str(),
+ GetLastError());
+ return false;
+ }
+
+ DWORD FileType = GetFileType(FileHandle);
+
+ if (FileType == FILE_TYPE_UNKNOWN) {
+ Printf("GetFileType() failed for \"%s\" (Error code: %lu).\n", Path.c_str(),
+ GetLastError());
+ CloseHandle(FileHandle);
+ return false;
+ }
+
+ if (FileType != FILE_TYPE_DISK) {
+ CloseHandle(FileHandle);
+ return false;
+ }
+
+ CloseHandle(FileHandle);
+ return true;
+}
+
+bool IsFile(const std::string &Path) {
+ DWORD Att = GetFileAttributesA(Path.c_str());
+
+ if (Att == INVALID_FILE_ATTRIBUTES) {
+ Printf("GetFileAttributesA() failed for \"%s\" (Error code: %lu).\n",
+ Path.c_str(), GetLastError());
+ return false;
+ }
+
+ return IsFile(Path, Att);
+}
+
+void ListFilesInDirRecursive(const std::string &Dir, long *Epoch,
+ std::vector<std::string> *V, bool TopDir) {
+ auto E = GetEpoch(Dir);
+ if (Epoch)
+ if (E && *Epoch >= E) return;
+
+ std::string Path(Dir);
+ assert(!Path.empty());
+ if (Path.back() != '\\')
+ Path.push_back('\\');
+ Path.push_back('*');
+
+ // Get the first directory entry.
+ WIN32_FIND_DATAA FindInfo;
+ HANDLE FindHandle(FindFirstFileA(Path.c_str(), &FindInfo));
+ if (FindHandle == INVALID_HANDLE_VALUE)
+ {
+ Printf("No file found in: %s.\n", Dir.c_str());
+ return;
+ }
+
+ do {
+ std::string FileName = DirPlusFile(Dir, FindInfo.cFileName);
+
+ if (FindInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ size_t FilenameLen = strlen(FindInfo.cFileName);
+ if ((FilenameLen == 1 && FindInfo.cFileName[0] == '.') ||
+ (FilenameLen == 2 && FindInfo.cFileName[0] == '.' &&
+ FindInfo.cFileName[1] == '.'))
+ continue;
+
+ ListFilesInDirRecursive(FileName, Epoch, V, false);
+ }
+ else if (IsFile(FileName, FindInfo.dwFileAttributes))
+ V->push_back(FileName);
+ } while (FindNextFileA(FindHandle, &FindInfo));
+
+ DWORD LastError = GetLastError();
+ if (LastError != ERROR_NO_MORE_FILES)
+ Printf("FindNextFileA failed (Error code: %lu).\n", LastError);
+
+ FindClose(FindHandle);
+
+ if (Epoch && TopDir)
+ *Epoch = E;
+}
+
+char GetSeparator() {
+ return '\\';
+}
+
+FILE* OpenFile(int Fd, const char* Mode) {
+ return _fdopen(Fd, Mode);
+}
+
+int CloseFile(int Fd) {
+ return _close(Fd);
+}
+
+int DuplicateFile(int Fd) {
+ return _dup(Fd);
+}
+
+void DeleteFile(const std::string &Path) {
+ _unlink(Path.c_str());
+}
+
+} // namespace fuzzer
+#endif // LIBFUZZER_WINDOWS