summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimur Iskhodzhanov <timurrrr@google.com>2015-04-09 15:25:21 +0000
committerTimur Iskhodzhanov <timurrrr@google.com>2015-04-09 15:25:21 +0000
commit0dda86f2b6d90d887fdcb4a0e13735bd9a647b73 (patch)
treef26129c982cb0aded60ef1a310fa2c887e037126
parentb8ba7903a9434a888aa65ed32c2ead2c574fe4d2 (diff)
downloadcompiler-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.cc2
-rw-r--r--lib/sanitizer_common/sanitizer_internal_defs.h7
-rw-r--r--lib/sanitizer_common/sanitizer_libc.h6
-rw-r--r--lib/sanitizer_common/sanitizer_win.cc69
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) {