aboutsummaryrefslogtreecommitdiffstats
path: root/lib/System
diff options
context:
space:
mode:
authorShih-wei Liao <sliao@google.com>2010-04-28 01:47:00 -0700
committerShih-wei Liao <sliao@google.com>2010-04-28 01:47:00 -0700
commit7abe37e4aee38cc79d91dd069a37d7e91d5bef53 (patch)
treec13b26fc3d8909240f981988535c0b82dd9bf37c /lib/System
parent6037a7c3c97b651dd70e48ebe5453134713971ed (diff)
downloadexternal_llvm-7abe37e4aee38cc79d91dd069a37d7e91d5bef53.zip
external_llvm-7abe37e4aee38cc79d91dd069a37d7e91d5bef53.tar.gz
external_llvm-7abe37e4aee38cc79d91dd069a37d7e91d5bef53.tar.bz2
Sync upstream to r102410.
Re-turn on sdk. Change-Id: I91a890863989a67243b4d2dfd1ae09b843ebaeaf
Diffstat (limited to 'lib/System')
-rw-r--r--lib/System/Android.mk3
-rw-r--r--lib/System/CMakeLists.txt2
-rw-r--r--lib/System/DynamicLibrary.cpp60
-rw-r--r--lib/System/Memory.cpp3
-rw-r--r--lib/System/Program.cpp6
-rw-r--r--lib/System/SearchForAddressOfSpecialSymbol.cpp64
-rw-r--r--lib/System/Unix/Mutex.inc6
-rw-r--r--lib/System/Unix/Path.inc29
-rw-r--r--lib/System/Unix/Program.inc106
-rw-r--r--lib/System/Unix/Signals.inc27
-rw-r--r--lib/System/Valgrind.cpp54
-rw-r--r--lib/System/Win32/Path.inc22
-rw-r--r--lib/System/Win32/Program.inc34
-rw-r--r--lib/System/Win32/Signals.inc1
14 files changed, 305 insertions, 112 deletions
diff --git a/lib/System/Android.mk b/lib/System/Android.mk
index 3f11fc7..e80ad69 100644
--- a/lib/System/Android.mk
+++ b/lib/System/Android.mk
@@ -16,7 +16,8 @@ system_SRC_FILES := \
Signals.cpp \
ThreadLocal.cpp \
Threading.cpp \
- TimeValue.cpp
+ TimeValue.cpp \
+ Valgrind.cpp
# For the host
# =====================================================
diff --git a/lib/System/CMakeLists.txt b/lib/System/CMakeLists.txt
index a56a1f7..b43c3af 100644
--- a/lib/System/CMakeLists.txt
+++ b/lib/System/CMakeLists.txt
@@ -12,10 +12,12 @@ add_llvm_library(LLVMSystem
Process.cpp
Program.cpp
RWMutex.cpp
+ SearchForAddressOfSpecialSymbol.cpp
Signals.cpp
ThreadLocal.cpp
Threading.cpp
TimeValue.cpp
+ Valgrind.cpp
Unix/Alarm.inc
Unix/Host.inc
Unix/Memory.inc
diff --git a/lib/System/DynamicLibrary.cpp b/lib/System/DynamicLibrary.cpp
index 63baa6d..6f6890c 100644
--- a/lib/System/DynamicLibrary.cpp
+++ b/lib/System/DynamicLibrary.cpp
@@ -24,12 +24,18 @@
// Collection of symbol name/value pairs to be searched prior to any libraries.
static std::map<std::string, void*> *ExplicitSymbols = 0;
-static struct ExplicitSymbolsDeleter {
+namespace {
+
+struct ExplicitSymbolsDeleter {
~ExplicitSymbolsDeleter() {
if (ExplicitSymbols)
delete ExplicitSymbols;
}
-} Dummy;
+};
+
+}
+
+static ExplicitSymbolsDeleter Dummy;
void llvm::sys::DynamicLibrary::AddSymbol(const char* symbolName,
void *symbolValue) {
@@ -44,6 +50,7 @@ void llvm::sys::DynamicLibrary::AddSymbol(const char* symbolName,
#else
+#if HAVE_DLFCN_H
#include <dlfcn.h>
using namespace llvm;
using namespace llvm::sys;
@@ -68,45 +75,20 @@ bool DynamicLibrary::LoadLibraryPermanently(const char *Filename,
OpenedHandles->push_back(H);
return false;
}
+#else
-static void *SearchForAddressOfSpecialSymbol(const char* symbolName) {
-#define EXPLICIT_SYMBOL(SYM) \
- extern void *SYM; if (!strcmp(symbolName, #SYM)) return &SYM
-
- // If this is darwin, it has some funky issues, try to solve them here. Some
- // important symbols are marked 'private external' which doesn't allow
- // SearchForAddressOfSymbol to find them. As such, we special case them here,
- // there is only a small handful of them.
-
-#ifdef __APPLE__
- {
- EXPLICIT_SYMBOL(__ashldi3);
- EXPLICIT_SYMBOL(__ashrdi3);
- EXPLICIT_SYMBOL(__cmpdi2);
- EXPLICIT_SYMBOL(__divdi3);
- EXPLICIT_SYMBOL(__eprintf);
- EXPLICIT_SYMBOL(__fixdfdi);
- EXPLICIT_SYMBOL(__fixsfdi);
- EXPLICIT_SYMBOL(__fixunsdfdi);
- EXPLICIT_SYMBOL(__fixunssfdi);
- EXPLICIT_SYMBOL(__floatdidf);
- EXPLICIT_SYMBOL(__floatdisf);
- EXPLICIT_SYMBOL(__lshrdi3);
- EXPLICIT_SYMBOL(__moddi3);
- EXPLICIT_SYMBOL(__udivdi3);
- EXPLICIT_SYMBOL(__umoddi3);
- }
-#endif
+using namespace llvm;
+using namespace llvm::sys;
-#ifdef __CYGWIN__
- {
- EXPLICIT_SYMBOL(_alloca);
- EXPLICIT_SYMBOL(__main);
- }
+bool DynamicLibrary::LoadLibraryPermanently(const char *Filename,
+ std::string *ErrMsg) {
+ if (ErrMsg) *ErrMsg = "dlopen() not supported on this platform";
+ return true;
+}
#endif
-#undef EXPLICIT_SYMBOL
- return 0;
+namespace llvm {
+void *SearchForAddressOfSpecialSymbol(const char* symbolName);
}
void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
@@ -120,6 +102,7 @@ void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
return I->second;
}
+#if HAVE_DLFCN_H
// Now search the libraries.
if (OpenedHandles) {
for (std::vector<void *>::iterator I = OpenedHandles->begin(),
@@ -131,8 +114,9 @@ void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
}
}
}
+#endif
- if (void *Result = SearchForAddressOfSpecialSymbol(symbolName))
+ if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName))
return Result;
// This macro returns the address of a well-known, explicit symbol
diff --git a/lib/System/Memory.cpp b/lib/System/Memory.cpp
index e2d838d..ef23b8d 100644
--- a/lib/System/Memory.cpp
+++ b/lib/System/Memory.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/System/Memory.h"
+#include "llvm/System/Valgrind.h"
#include "llvm/Config/config.h"
namespace llvm {
@@ -68,4 +69,6 @@ void llvm::sys::Memory::InvalidateInstructionCache(const void *Addr,
# endif
#endif // end apple
+
+ ValgrindDiscardTranslations(Addr, Len);
}
diff --git a/lib/System/Program.cpp b/lib/System/Program.cpp
index a3049d46..cd58c2c 100644
--- a/lib/System/Program.cpp
+++ b/lib/System/Program.cpp
@@ -13,8 +13,7 @@
#include "llvm/System/Program.h"
#include "llvm/Config/config.h"
-
-namespace llvm {
+using namespace llvm;
using namespace sys;
//===----------------------------------------------------------------------===//
@@ -48,9 +47,6 @@ Program::ExecuteNoWait(const Path& path,
prg.Execute(path, args, envp, redirects, memoryLimit, ErrMsg);
}
-
-}
-
// Include the platform-specific parts of this class.
#ifdef LLVM_ON_UNIX
#include "Unix/Program.inc"
diff --git a/lib/System/SearchForAddressOfSpecialSymbol.cpp b/lib/System/SearchForAddressOfSpecialSymbol.cpp
new file mode 100644
index 0000000..73b484c
--- /dev/null
+++ b/lib/System/SearchForAddressOfSpecialSymbol.cpp
@@ -0,0 +1,64 @@
+//===- SearchForAddressOfSpecialSymbol.cpp - Function addresses -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file pulls the addresses of certain symbols out of the linker. It must
+// include as few header files as possible because it declares the symbols as
+// void*, which would conflict with the actual symbol type if any header
+// declared it.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+
+// Must declare the symbols in the global namespace.
+static void *DoSearch(const char* symbolName) {
+#define EXPLICIT_SYMBOL(SYM) \
+ extern void *SYM; if (!strcmp(symbolName, #SYM)) return &SYM
+
+ // If this is darwin, it has some funky issues, try to solve them here. Some
+ // important symbols are marked 'private external' which doesn't allow
+ // SearchForAddressOfSymbol to find them. As such, we special case them here,
+ // there is only a small handful of them.
+
+#ifdef __APPLE__
+ {
+ EXPLICIT_SYMBOL(__ashldi3);
+ EXPLICIT_SYMBOL(__ashrdi3);
+ EXPLICIT_SYMBOL(__cmpdi2);
+ EXPLICIT_SYMBOL(__divdi3);
+ EXPLICIT_SYMBOL(__eprintf);
+ EXPLICIT_SYMBOL(__fixdfdi);
+ EXPLICIT_SYMBOL(__fixsfdi);
+ EXPLICIT_SYMBOL(__fixunsdfdi);
+ EXPLICIT_SYMBOL(__fixunssfdi);
+ EXPLICIT_SYMBOL(__floatdidf);
+ EXPLICIT_SYMBOL(__floatdisf);
+ EXPLICIT_SYMBOL(__lshrdi3);
+ EXPLICIT_SYMBOL(__moddi3);
+ EXPLICIT_SYMBOL(__udivdi3);
+ EXPLICIT_SYMBOL(__umoddi3);
+ }
+#endif
+
+#ifdef __CYGWIN__
+ {
+ EXPLICIT_SYMBOL(_alloca);
+ EXPLICIT_SYMBOL(__main);
+ }
+#endif
+
+#undef EXPLICIT_SYMBOL
+ return 0;
+}
+
+namespace llvm {
+void *SearchForAddressOfSpecialSymbol(const char* symbolName) {
+ return DoSearch(symbolName);
+}
+} // namespace llvm
diff --git a/lib/System/Unix/Mutex.inc b/lib/System/Unix/Mutex.inc
index 10e7ecb..4a5e28d 100644
--- a/lib/System/Unix/Mutex.inc
+++ b/lib/System/Unix/Mutex.inc
@@ -29,12 +29,6 @@ MutexImpl::~MutexImpl()
}
bool
-MutexImpl::MutexImpl()
-{
- return true;
-}
-
-bool
MutexImpl::release()
{
return true;
diff --git a/lib/System/Unix/Path.inc b/lib/System/Unix/Path.inc
index a99720c..74596dc 100644
--- a/lib/System/Unix/Path.inc
+++ b/lib/System/Unix/Path.inc
@@ -454,7 +454,7 @@ Path::canWrite() const {
bool
Path::isRegularFile() const {
- // Get the status so we can determine if its a file or directory
+ // Get the status so we can determine if it's a file or directory
struct stat buf;
if (0 != stat(path.c_str(), &buf))
@@ -736,7 +736,7 @@ Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) {
bool
Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
- // Get the status so we can determine if its a file or directory
+ // Get the status so we can determine if it's a file or directory.
struct stat buf;
if (0 != stat(path.c_str(), &buf)) {
MakeErrMsg(ErrStr, path + ": can't get status of file");
@@ -858,15 +858,20 @@ Path::makeUnique(bool reuse_current, std::string* ErrMsg) {
// Append an XXXXXX pattern to the end of the file for use with mkstemp,
// mktemp or our own implementation.
- std::string Buf(path);
+ // This uses std::vector instead of SmallVector to avoid a dependence on
+ // libSupport. And performance isn't critical here.
+ std::vector<char> Buf;
+ Buf.resize(path.size()+8);
+ char *FNBuffer = &Buf[0];
+ path.copy(FNBuffer,path.size());
if (isDirectory())
- Buf += "/XXXXXX";
+ strcpy(FNBuffer+path.size(), "/XXXXXX");
else
- Buf += "-XXXXXX";
+ strcpy(FNBuffer+path.size(), "-XXXXXX");
#if defined(HAVE_MKSTEMP)
int TempFD;
- if ((TempFD = mkstemp((char*)Buf.c_str())) == -1)
+ if ((TempFD = mkstemp(FNBuffer)) == -1)
return MakeErrMsg(ErrMsg, path + ": can't make unique filename");
// We don't need to hold the temp file descriptor... we will trust that no one
@@ -874,21 +879,21 @@ Path::makeUnique(bool reuse_current, std::string* ErrMsg) {
close(TempFD);
// Save the name
- path = Buf;
+ path = FNBuffer;
#elif defined(HAVE_MKTEMP)
// If we don't have mkstemp, use the old and obsolete mktemp function.
- if (mktemp(Buf.c_str()) == 0)
+ if (mktemp(FNBuffer) == 0)
return MakeErrMsg(ErrMsg, path + ": can't make unique filename");
// Save the name
- path = Buf;
+ path = FNBuffer;
#else
// Okay, looks like we have to do it all by our lonesome.
static unsigned FCounter = 0;
unsigned offset = path.size() + 1;
- while (FCounter < 999999 && exists()) {
- sprintf(Buf.data()+offset, "%06u", ++FCounter);
- path = Buf;
+ while ( FCounter < 999999 && exists()) {
+ sprintf(FNBuffer+offset,"%06u",++FCounter);
+ path = FNBuffer;
}
if (FCounter > 999999)
return MakeErrMsg(ErrMsg,
diff --git a/lib/System/Unix/Program.inc b/lib/System/Unix/Program.inc
index c10498a..358415f 100644
--- a/lib/System/Unix/Program.inc
+++ b/lib/System/Unix/Program.inc
@@ -30,6 +30,14 @@
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
+#ifdef HAVE_POSIX_SPAWN
+#include <spawn.h>
+#if !defined(__APPLE__)
+ extern char **environ;
+#else
+#include <crt_externs.h> // _NSGetEnviron
+#endif
+#endif
namespace llvm {
using namespace sys;
@@ -94,33 +102,52 @@ Program::FindProgramByName(const std::string& progName) {
}
static bool RedirectIO(const Path *Path, int FD, std::string* ErrMsg) {
- if (Path == 0)
- // Noop
+ if (Path == 0) // Noop
return false;
- std::string File;
+ const char *File;
if (Path->isEmpty())
// Redirect empty paths to /dev/null
File = "/dev/null";
else
- File = Path->str();
+ File = Path->c_str();
// Open the file
- int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
+ int InFD = open(File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
if (InFD == -1) {
- MakeErrMsg(ErrMsg, "Cannot open file '" + File + "' for "
+ MakeErrMsg(ErrMsg, "Cannot open file '" + std::string(File) + "' for "
+ (FD == 0 ? "input" : "output"));
return true;
}
// Install it as the requested FD
- if (-1 == dup2(InFD, FD)) {
+ if (dup2(InFD, FD) == -1) {
MakeErrMsg(ErrMsg, "Cannot dup2");
+ close(InFD);
return true;
}
close(InFD); // Close the original FD
return false;
}
+#ifdef HAVE_POSIX_SPAWN
+static bool RedirectIO_PS(const Path *Path, int FD, std::string *ErrMsg,
+ posix_spawn_file_actions_t &FileActions) {
+ if (Path == 0) // Noop
+ return false;
+ const char *File;
+ if (Path->isEmpty())
+ // Redirect empty paths to /dev/null
+ File = "/dev/null";
+ else
+ File = Path->c_str();
+
+ if (int Err = posix_spawn_file_actions_addopen(&FileActions, FD,
+ File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666))
+ return MakeErrMsg(ErrMsg, "Cannot dup2", Err);
+ return false;
+}
+#endif
+
static void TimeOutHandler(int Sig) {
}
@@ -150,13 +177,55 @@ static void SetMemoryLimits (unsigned size)
}
bool
-Program::Execute(const Path& path,
- const char** args,
- const char** envp,
- const Path** redirects,
- unsigned memoryLimit,
- std::string* ErrMsg)
-{
+Program::Execute(const Path &path, const char **args, const char **envp,
+ const Path **redirects, unsigned memoryLimit,
+ std::string *ErrMsg) {
+ // If this OS has posix_spawn and there is no memory limit being implied, use
+ // posix_spawn. It is more efficient than fork/exec.
+#ifdef HAVE_POSIX_SPAWN
+ if (memoryLimit == 0) {
+ posix_spawn_file_actions_t FileActions;
+ posix_spawn_file_actions_init(&FileActions);
+
+ if (redirects) {
+ // Redirect stdin/stdout.
+ if (RedirectIO_PS(redirects[0], 0, ErrMsg, FileActions) ||
+ RedirectIO_PS(redirects[1], 1, ErrMsg, FileActions))
+ return false;
+ if (redirects[1] == 0 || redirects[2] == 0 ||
+ *redirects[1] != *redirects[2]) {
+ // Just redirect stderr
+ if (RedirectIO_PS(redirects[2], 2, ErrMsg, FileActions)) return false;
+ } else {
+ // If stdout and stderr should go to the same place, redirect stderr
+ // to the FD already open for stdout.
+ if (int Err = posix_spawn_file_actions_adddup2(&FileActions, 1, 2))
+ return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err);
+ }
+ }
+
+ if (!envp)
+#if !defined(__APPLE__)
+ envp = const_cast<const char **>(environ);
+#else
+ // environ is missing in dylibs.
+ envp = const_cast<const char **>(*_NSGetEnviron());
+#endif
+
+ pid_t PID;
+ int Err = posix_spawn(&PID, path.c_str(), &FileActions, /*attrp*/0,
+ const_cast<char **>(args), const_cast<char **>(envp));
+
+ posix_spawn_file_actions_destroy(&FileActions);
+
+ if (Err)
+ return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
+
+ Data_ = reinterpret_cast<void*>(PID);
+ return true;
+ }
+#endif
+
if (!path.canExecute()) {
if (ErrMsg)
*ErrMsg = path.str() + " is not executable";
@@ -200,9 +269,12 @@ Program::Execute(const Path& path,
// Execute!
if (envp != 0)
- execve(path.c_str(), (char**)args, (char**)envp);
+ execve(path.c_str(),
+ const_cast<char **>(args),
+ const_cast<char **>(envp));
else
- execv(path.c_str(), (char**)args);
+ execv(path.c_str(),
+ const_cast<char **>(args));
// If the execve() failed, we should exit. Follow Unix protocol and
// return 127 if the executable was not found, and 126 otherwise.
// Use _exit rather than exit so that atexit functions and static
@@ -238,7 +310,9 @@ Program::Wait(unsigned secondsToWait,
// fact of having a handler at all causes the wait below to return with EINTR,
// unlike if we used SIG_IGN.
if (secondsToWait) {
+#ifndef __HAIKU__
Act.sa_sigaction = 0;
+#endif
Act.sa_handler = TimeOutHandler;
sigemptyset(&Act.sa_mask);
Act.sa_flags = 0;
diff --git a/lib/System/Unix/Signals.inc b/lib/System/Unix/Signals.inc
index c8ec68a..56bf9e7 100644
--- a/lib/System/Unix/Signals.inc
+++ b/lib/System/Unix/Signals.inc
@@ -39,8 +39,8 @@ static SmartMutex<true> SignalsMutex;
/// InterruptFunction - The function to call if ctrl-c is pressed.
static void (*InterruptFunction)() = 0;
-static std::vector<sys::Path> *FilesToRemove = 0;
-static std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0;
+static std::vector<sys::Path> FilesToRemove;
+static std::vector<std::pair<void(*)(void*), void*> > CallBacksToRun;
// IntSigs - Signals that may interrupt the program at any time.
static const int IntSigs[] = {
@@ -126,11 +126,10 @@ static RETSIGTYPE SignalHandler(int Sig) {
sigprocmask(SIG_UNBLOCK, &SigMask, 0);
SignalsMutex.acquire();
- if (FilesToRemove != 0)
- while (!FilesToRemove->empty()) {
- FilesToRemove->back().eraseFromDisk(true);
- FilesToRemove->pop_back();
- }
+ while (!FilesToRemove.empty()) {
+ FilesToRemove.back().eraseFromDisk(true);
+ FilesToRemove.pop_back();
+ }
if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd) {
if (InterruptFunction) {
@@ -149,9 +148,8 @@ static RETSIGTYPE SignalHandler(int Sig) {
SignalsMutex.release();
// Otherwise if it is a fault (like SEGV) run any handler.
- if (CallBacksToRun)
- for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i)
- (*CallBacksToRun)[i].first((*CallBacksToRun)[i].second);
+ for (unsigned i = 0, e = CallBacksToRun.size(); i != e; ++i)
+ CallBacksToRun[i].first(CallBacksToRun[i].second);
}
@@ -167,10 +165,7 @@ void llvm::sys::SetInterruptFunction(void (*IF)()) {
bool llvm::sys::RemoveFileOnSignal(const sys::Path &Filename,
std::string* ErrMsg) {
SignalsMutex.acquire();
- if (FilesToRemove == 0)
- FilesToRemove = new std::vector<sys::Path>();
-
- FilesToRemove->push_back(Filename);
+ FilesToRemove.push_back(Filename);
SignalsMutex.release();
@@ -182,9 +177,7 @@ bool llvm::sys::RemoveFileOnSignal(const sys::Path &Filename,
/// to the process. The handler can have a cookie passed to it to identify
/// what instance of the handler it is.
void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
- if (CallBacksToRun == 0)
- CallBacksToRun = new std::vector<std::pair<void(*)(void*), void*> >();
- CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie));
+ CallBacksToRun.push_back(std::make_pair(FnPtr, Cookie));
RegisterHandlers();
}
diff --git a/lib/System/Valgrind.cpp b/lib/System/Valgrind.cpp
new file mode 100644
index 0000000..c76cfe4
--- /dev/null
+++ b/lib/System/Valgrind.cpp
@@ -0,0 +1,54 @@
+//===-- Valgrind.cpp - Implement Valgrind communication ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines Valgrind communication methods, if HAVE_VALGRIND_VALGRIND_H is
+// defined. If we have valgrind.h but valgrind isn't running, its macros are
+// no-ops.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/System/Valgrind.h"
+#include "llvm/Config/config.h"
+
+#if HAVE_VALGRIND_VALGRIND_H
+#include <valgrind/valgrind.h>
+
+static bool InitNotUnderValgrind() {
+ return !RUNNING_ON_VALGRIND;
+}
+
+// This bool is negated from what we'd expect because code may run before it
+// gets initialized. If that happens, it will appear to be 0 (false), and we
+// want that to cause the rest of the code in this file to run the
+// Valgrind-provided macros.
+static const bool NotUnderValgrind = InitNotUnderValgrind();
+
+bool llvm::sys::RunningOnValgrind() {
+ if (NotUnderValgrind)
+ return false;
+ return RUNNING_ON_VALGRIND;
+}
+
+void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
+ if (NotUnderValgrind)
+ return;
+
+ VALGRIND_DISCARD_TRANSLATIONS(Addr, Len);
+}
+
+#else // !HAVE_VALGRIND_VALGRIND_H
+
+bool llvm::sys::RunningOnValgrind() {
+ return false;
+}
+
+void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
+}
+
+#endif // !HAVE_VALGRIND_VALGRIND_H
diff --git a/lib/System/Win32/Path.inc b/lib/System/Win32/Path.inc
index b5f6374..5a0052f 100644
--- a/lib/System/Win32/Path.inc
+++ b/lib/System/Win32/Path.inc
@@ -126,7 +126,7 @@ Path::isValid() const {
}
void Path::makeAbsolute() {
- TCHAR FullPath[MAX_PATH + 1] = {0};
+ TCHAR FullPath[MAX_PATH + 1] = {0};
LPTSTR FilePart = NULL;
DWORD RetLength = ::GetFullPathNameA(path.c_str(),
@@ -161,7 +161,7 @@ Path::isAbsolute(const char *NameStart, unsigned NameLen) {
}
}
-bool
+bool
Path::isAbsolute() const {
// FIXME: This does not handle correctly an absolute path starting from
// a drive letter or in UNC format.
@@ -174,9 +174,9 @@ Path::isAbsolute() const {
default:
return path[0] == '/' || (path[1] == ':' && path[2] == '/');
}
-}
+}
-static Path *TempDirectory = NULL;
+static Path *TempDirectory;
Path
Path::GetTemporaryDirectory(std::string* ErrMsg) {
@@ -266,7 +266,7 @@ Path
Path::GetCurrentDirectory() {
char pathname[MAX_PATH];
::GetCurrentDirectoryA(MAX_PATH,pathname);
- return Path(pathname);
+ return Path(pathname);
}
/// GetMainExecutable - Return the path to the main executable, given the
@@ -448,7 +448,7 @@ Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const {
MakeErrMsg(ErrMsg, path + ": can't get status of file");
return true;
}
-
+
if (!(fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if (ErrMsg)
*ErrMsg = path + ": not a directory";
@@ -617,7 +617,7 @@ Path::createDirectoryOnDisk(bool create_parents, std::string* ErrMsg) {
*next = 0;
if (!CreateDirectory(pathname, NULL) &&
GetLastError() != ERROR_ALREADY_EXISTS)
- return MakeErrMsg(ErrMsg,
+ return MakeErrMsg(ErrMsg,
std::string(pathname) + ": Can't create directory: ");
*next++ = '/';
}
@@ -649,7 +649,7 @@ Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
WIN32_FILE_ATTRIBUTE_DATA fi;
if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi))
return true;
-
+
if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
// If it doesn't exist, we're done.
if (!exists())
@@ -706,7 +706,7 @@ Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
pathname[lastchar] = 0;
if (!RemoveDirectory(pathname))
- return MakeErrMsg(ErrStr,
+ return MakeErrMsg(ErrStr,
std::string(pathname) + ": Can't destroy directory: ");
return false;
} else {
@@ -753,7 +753,7 @@ bool Path::getMagicNumber(std::string& Magic, unsigned len) const {
bool
Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) {
if (!MoveFileEx(path.c_str(), newName.c_str(), MOVEFILE_REPLACE_EXISTING))
- return MakeErrMsg(ErrMsg, "Can't move '" + path + "' to '" + newName.path
+ return MakeErrMsg(ErrMsg, "Can't move '" + path + "' to '" + newName.path
+ "': ");
return false;
}
@@ -764,7 +764,7 @@ Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrMsg) const {
if (!si.isFile) {
return true;
}
-
+
HANDLE h = CreateFile(path.c_str(),
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
diff --git a/lib/System/Win32/Program.inc b/lib/System/Win32/Program.inc
index a3b40d0..16bb28e 100644
--- a/lib/System/Win32/Program.inc
+++ b/lib/System/Win32/Program.inc
@@ -138,6 +138,24 @@ static bool ArgNeedsQuotes(const char *Str) {
return Str[0] == '\0' || strchr(Str, ' ') != 0;
}
+
+/// ArgLenWithQuotes - Check whether argument needs to be quoted when calling
+/// CreateProcess and returns length of quoted arg with escaped quotes
+static unsigned int ArgLenWithQuotes(const char *Str) {
+ unsigned int len = ArgNeedsQuotes(Str) ? 2 : 0;
+
+ while (*Str != '\0') {
+ if (*Str == '\"')
+ ++len;
+
+ ++len;
+ ++Str;
+ }
+
+ return len;
+}
+
+
bool
Program::Execute(const Path& path,
const char** args,
@@ -165,9 +183,7 @@ Program::Execute(const Path& path,
// First, determine the length of the command line.
unsigned len = 0;
for (unsigned i = 0; args[i]; i++) {
- len += strlen(args[i]) + 1;
- if (ArgNeedsQuotes(args[i]))
- len += 2;
+ len += ArgLenWithQuotes(args[i]) + 1;
}
// Now build the command line.
@@ -176,12 +192,18 @@ Program::Execute(const Path& path,
for (unsigned i = 0; args[i]; i++) {
const char *arg = args[i];
- size_t len = strlen(arg);
+
bool needsQuoting = ArgNeedsQuotes(arg);
if (needsQuoting)
*p++ = '"';
- memcpy(p, arg, len);
- p += len;
+
+ while (*arg != '\0') {
+ if (*arg == '\"')
+ *p++ = '\\';
+
+ *p++ = *arg++;
+ }
+
if (needsQuoting)
*p++ = '"';
*p++ = ' ';
diff --git a/lib/System/Win32/Signals.inc b/lib/System/Win32/Signals.inc
index dba2218..f2b72ca 100644
--- a/lib/System/Win32/Signals.inc
+++ b/lib/System/Win32/Signals.inc
@@ -163,6 +163,7 @@ void sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
CallBacksToRun = new std::vector<std::pair<void(*)(void*), void*> >();
CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie));
RegisterHandler();
+ LeaveCriticalSection(&CriticalSection);
}
}