diff options
author | Zachary Turner <zturner@google.com> | 2016-11-30 21:44:26 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2016-11-30 21:44:26 +0000 |
commit | 5abac1769f36e4f7d9d6c3a408a1356490fc76e0 (patch) | |
tree | e669c5f43b78ba2a55aae705aff4fce55581d6e6 /llvm/lib/Fuzzer/FuzzerIOWindows.cpp | |
parent | b151a641aa8fe3c1bbb2ed78279ede5f1ecc0e7e (diff) | |
download | bcm5719-llvm-5abac1769f36e4f7d9d6c3a408a1356490fc76e0.tar.gz bcm5719-llvm-5abac1769f36e4f7d9d6c3a408a1356490fc76e0.zip |
[LibFuzzer] Add Windows implementations of some IO functions.
This patch moves some posix specific file i/o code into a new
file, FuzzerIOPosix.cpp, and provides implementations for these
functions on Windows in FuzzerIOWindows.cpp. This is another
incremental step towards getting libfuzzer working on Windows,
although it still should not be expected to be fully working.
Patch by Marcos Pividori
Differential Revision: https://reviews.llvm.org/D27233
llvm-svn: 288275
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerIOWindows.cpp')
-rw-r--r-- | llvm/lib/Fuzzer/FuzzerIOWindows.cpp | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerIOWindows.cpp b/llvm/lib/Fuzzer/FuzzerIOWindows.cpp new file mode 100644 index 00000000000..f19353c96cb --- /dev/null +++ b/llvm/lib/Fuzzer/FuzzerIOWindows.cpp @@ -0,0 +1,143 @@ +//===- 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 |