diff options
author | Timur Iskhodzhanov <timurrrr@google.com> | 2015-04-09 15:25:21 +0000 |
---|---|---|
committer | Timur Iskhodzhanov <timurrrr@google.com> | 2015-04-09 15:25:21 +0000 |
commit | 0dda86f2b6d90d887fdcb4a0e13735bd9a647b73 (patch) | |
tree | f26129c982cb0aded60ef1a310fa2c887e037126 | |
parent | b8ba7903a9434a888aa65ed32c2ead2c574fe4d2 (diff) | |
download | compiler-rt-0dda86f2b6d90d887fdcb4a0e13735bd9a647b73.tar.gz |
[ASan/Win] Add more support for file operations
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@234494 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/sanitizer_common/sanitizer_coverage_libcdep.cc | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_internal_defs.h | 7 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_libc.h | 6 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_win.cc | 69 |
4 files changed, 32 insertions, 52 deletions
diff --git a/lib/sanitizer_common/sanitizer_coverage_libcdep.cc b/lib/sanitizer_common/sanitizer_coverage_libcdep.cc index ae3c08075..c358437b6 100644 --- a/lib/sanitizer_common/sanitizer_coverage_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_coverage_libcdep.cc @@ -804,7 +804,7 @@ void CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args) { if (!cov_sandboxed) return; cov_max_block_size = args->coverage_max_block_size; if (args->coverage_fd >= 0) { - cov_fd = args->coverage_fd; + cov_fd = (fd_t)args->coverage_fd; } else { InternalScopedString path(kMaxPathLength); // Pre-open the file now. The sandbox won't allow us to do it later. diff --git a/lib/sanitizer_common/sanitizer_internal_defs.h b/lib/sanitizer_common/sanitizer_internal_defs.h index 83d46c5cd..b76c6023a 100644 --- a/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/lib/sanitizer_common/sanitizer_internal_defs.h @@ -80,8 +80,15 @@ typedef signed char s8; typedef signed short s16; // NOLINT typedef signed int s32; typedef signed long long s64; // NOLINT +#if SANITIZER_WINDOWS +// On Windows, files are HANDLE, which is a synonim of void*. +// Use void* to avoid including <windows.h> everywhere. +typedef void* fd_t; +typedef unsigned error_t; +#else typedef int fd_t; typedef int error_t; +#endif // WARNING: OFF_T may be different from OS type off_t, depending on the value of // _FILE_OFFSET_BITS. This definition of OFF_T matches the ABI of system calls diff --git a/lib/sanitizer_common/sanitizer_libc.h b/lib/sanitizer_common/sanitizer_libc.h index b8cad2446..ae4e938f4 100644 --- a/lib/sanitizer_common/sanitizer_libc.h +++ b/lib/sanitizer_common/sanitizer_libc.h @@ -58,10 +58,10 @@ int internal_snprintf(char *buffer, uptr length, const char *format, ...); bool mem_is_zero(const char *mem, uptr size); // I/O -const fd_t kInvalidFd = -1; +const fd_t kInvalidFd = (fd_t)-1; const fd_t kStdinFd = 0; -const fd_t kStdoutFd = 1; -const fd_t kStderrFd = 2; +const fd_t kStdoutFd = (fd_t)1; +const fd_t kStderrFd = (fd_t)2; uptr internal_ftruncate(fd_t fd, uptr size); diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc index 96eb249dd..c081daa4c 100644 --- a/lib/sanitizer_common/sanitizer_win.cc +++ b/lib/sanitizer_common/sanitizer_win.cc @@ -396,11 +396,17 @@ static __declspec(allocate(".CRT$XID")) int (*__run_atexit)() = RunAtexit; // ------------------ sanitizer_libc.h fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *last_error) { - UNIMPLEMENTED(); + if (mode != WrOnly) + UNIMPLEMENTED(); + fd_t res = CreateFile(filename, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, nullptr); + CHECK(res != kStdoutFd || kStdoutFd == kInvalidFd); + CHECK(res != kStderrFd || kStderrFd == kInvalidFd); + return res; } void CloseFile(fd_t fd) { - UNIMPLEMENTED(); + CloseHandle(fd); } bool ReadFromFile(fd_t fd, void *buff, uptr buff_size, uptr *bytes_read, @@ -415,58 +421,25 @@ bool SupportsColoredOutput(fd_t fd) { bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written, error_t *error_p) { - if (fd != kStderrFd) - UNIMPLEMENTED(); - - static HANDLE output_stream = 0; - // Abort immediately if we know printing is not possible. - if (output_stream == INVALID_HANDLE_VALUE) { - if (error_p) *error_p = ERROR_INVALID_HANDLE; - return false; - } - - // If called for the first time, try to use stderr to output stuff, - // falling back to stdout if anything goes wrong. - bool fallback_to_stdout = false; - if (output_stream == 0) { - output_stream = GetStdHandle(STD_ERROR_HANDLE); - // We don't distinguish "no such handle" from error. - if (output_stream == 0) - output_stream = INVALID_HANDLE_VALUE; - - if (output_stream == INVALID_HANDLE_VALUE) { - // Retry with stdout? - output_stream = GetStdHandle(STD_OUTPUT_HANDLE); - if (output_stream == 0) - output_stream = INVALID_HANDLE_VALUE; - if (output_stream == INVALID_HANDLE_VALUE) { - if (error_p) *error_p = ERROR_INVALID_HANDLE; - return false; - } - } else { - // Successfully got an stderr handle. However, if WriteFile() fails, - // we can still try to fallback to stdout. - fallback_to_stdout = true; - } + CHECK(fd != kInvalidFd); + + if (fd == kStdoutFd) { + fd = GetStdHandle(STD_OUTPUT_HANDLE); + if (fd == 0) fd = kInvalidFd; + } else if (fd == kStderrFd) { + fd = GetStdHandle(STD_ERROR_HANDLE); + if (fd == 0) fd = kInvalidFd; } DWORD internal_bytes_written; - if (WriteFile(output_stream, buff, buff_size, &internal_bytes_written, 0)) { + if (fd == kInvalidFd || + WriteFile(fd, buff, buff_size, &internal_bytes_written, 0)) { + if (error_p) *error_p = GetLastError(); + return false; + } else { if (bytes_written) *bytes_written = internal_bytes_written; return true; } - - // Re-try with stdout if using a valid stderr handle fails. - if (fallback_to_stdout) { - output_stream = GetStdHandle(STD_OUTPUT_HANDLE); - if (output_stream == 0) - output_stream = INVALID_HANDLE_VALUE; - if (output_stream != INVALID_HANDLE_VALUE) - return WriteToFile(fd, buff, buff_size, bytes_written, error_p); - } - - if (error_p) *error_p = GetLastError(); - return false; } bool RenameFile(const char *oldpath, const char *newpath, error_t *error_p) { |