summaryrefslogtreecommitdiff
path: root/llvm/lib/Support/Windows/Process.inc
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Support/Windows/Process.inc')
-rw-r--r--llvm/lib/Support/Windows/Process.inc48
1 files changed, 37 insertions, 11 deletions
diff --git a/llvm/lib/Support/Windows/Process.inc b/llvm/lib/Support/Windows/Process.inc
index 3526e3dee6fa1..8064d4e17b295 100644
--- a/llvm/lib/Support/Windows/Process.inc
+++ b/llvm/lib/Support/Windows/Process.inc
@@ -19,7 +19,7 @@
#include <malloc.h>
// The Windows.h header must be after LLVM and standard headers.
-#include "WindowsSupport.h"
+#include "llvm/Support/Windows/WindowsSupport.h"
#include <direct.h>
#include <io.h>
@@ -43,6 +43,12 @@
using namespace llvm;
+Process::Pid Process::getProcessId() {
+ static_assert(sizeof(Pid) >= sizeof(DWORD),
+ "Process::Pid should be big enough to store DWORD");
+ return Pid(::GetCurrentProcessId());
+}
+
// This function retrieves the page size using GetNativeSystemInfo() and is
// present solely so it can be called once to initialize the self_process member
// below.
@@ -439,18 +445,38 @@ const char *Process::ResetColor() {
return 0;
}
+static unsigned GetRandomNumberSeed() {
+ // Generate a random number seed from the millisecond-resolution Windows
+ // system clock and the current process id.
+ FILETIME Time;
+ GetSystemTimeAsFileTime(&Time);
+ DWORD Pid = GetCurrentProcessId();
+ return hash_combine(Time.dwHighDateTime, Time.dwLowDateTime, Pid);
+}
+
+static unsigned GetPseudoRandomNumber() {
+ // Arrange to call srand once when this function is first used, and
+ // otherwise (if GetRandomNumber always succeeds in using
+ // CryptGenRandom) don't bother at all.
+ static int x = (static_cast<void>(::srand(GetRandomNumberSeed())), 0);
+ (void)x;
+ return ::rand();
+}
+
unsigned Process::GetRandomNumber() {
+ // Try to use CryptGenRandom.
HCRYPTPROV HCPC;
- if (!::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT))
- ReportLastErrorFatal("Could not acquire a cryptographic context");
-
- ScopedCryptContext CryptoProvider(HCPC);
- unsigned Ret;
- if (!::CryptGenRandom(CryptoProvider, sizeof(Ret),
- reinterpret_cast<BYTE *>(&Ret)))
- ReportLastErrorFatal("Could not generate a random number");
- return Ret;
+ if (::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT)) {
+ ScopedCryptContext CryptoProvider(HCPC);
+ unsigned Ret;
+ if (::CryptGenRandom(CryptoProvider, sizeof(Ret),
+ reinterpret_cast<BYTE *>(&Ret)))
+ return Ret;
+ }
+
+ // If that fails, fall back to pseudo-random numbers.
+ return GetPseudoRandomNumber();
}
typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);