diff options
author | dim <dim@FreeBSD.org> | 2011-02-20 12:57:14 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-02-20 12:57:14 +0000 |
commit | cbb70ce070d220642b038ea101d9c0f9fbf860d6 (patch) | |
tree | d2b61ce94e654cb01a254d2195259db5f9cc3f3c /lib/System | |
parent | 4ace901e87dac5bbbac78ed325e75462e48e386e (diff) | |
download | FreeBSD-src-cbb70ce070d220642b038ea101d9c0f9fbf860d6.zip FreeBSD-src-cbb70ce070d220642b038ea101d9c0f9fbf860d6.tar.gz |
Vendor import of llvm trunk r126079:
http://llvm.org/svn/llvm-project/llvm/trunk@126079
Diffstat (limited to 'lib/System')
48 files changed, 0 insertions, 6955 deletions
diff --git a/lib/System/Alarm.cpp b/lib/System/Alarm.cpp deleted file mode 100644 index 0014ca7..0000000 --- a/lib/System/Alarm.cpp +++ /dev/null @@ -1,33 +0,0 @@ -//===- Alarm.cpp - Alarm Generation Support ---------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Alarm functionality -// -//===----------------------------------------------------------------------===// - -#include "llvm/System/Alarm.h" -#include "llvm/Config/config.h" - -namespace llvm { -using namespace sys; - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only TRULY operating system -//=== independent code. -//===----------------------------------------------------------------------===// - -} - -// Include the platform-specific parts of this class. -#ifdef LLVM_ON_UNIX -#include "Unix/Alarm.inc" -#endif -#ifdef LLVM_ON_WIN32 -#include "Win32/Alarm.inc" -#endif diff --git a/lib/System/Atomic.cpp b/lib/System/Atomic.cpp deleted file mode 100644 index 7ba8b77..0000000 --- a/lib/System/Atomic.cpp +++ /dev/null @@ -1,112 +0,0 @@ -//===-- Atomic.cpp - Atomic Operations --------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This header file implements atomic operations. -// -//===----------------------------------------------------------------------===// - -#include "llvm/System/Atomic.h" -#include "llvm/Config/config.h" - -using namespace llvm; - -#if defined(_MSC_VER) -#include <windows.h> -#undef MemoryFence -#endif - -void sys::MemoryFence() { -#if LLVM_MULTITHREADED==0 - return; -#else -# if defined(__GNUC__) - __sync_synchronize(); -# elif defined(_MSC_VER) - MemoryBarrier(); -# else -# error No memory fence implementation for your platform! -# endif -#endif -} - -sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr, - sys::cas_flag new_value, - sys::cas_flag old_value) { -#if LLVM_MULTITHREADED==0 - sys::cas_flag result = *ptr; - if (result == old_value) - *ptr = new_value; - return result; -#elif defined(__GNUC__) - return __sync_val_compare_and_swap(ptr, old_value, new_value); -#elif defined(_MSC_VER) - return InterlockedCompareExchange(ptr, new_value, old_value); -#else -# error No compare-and-swap implementation for your platform! -#endif -} - -sys::cas_flag sys::AtomicIncrement(volatile sys::cas_flag* ptr) { -#if LLVM_MULTITHREADED==0 - ++(*ptr); - return *ptr; -#elif defined(__GNUC__) - return __sync_add_and_fetch(ptr, 1); -#elif defined(_MSC_VER) - return InterlockedIncrement(ptr); -#else -# error No atomic increment implementation for your platform! -#endif -} - -sys::cas_flag sys::AtomicDecrement(volatile sys::cas_flag* ptr) { -#if LLVM_MULTITHREADED==0 - --(*ptr); - return *ptr; -#elif defined(__GNUC__) - return __sync_sub_and_fetch(ptr, 1); -#elif defined(_MSC_VER) - return InterlockedDecrement(ptr); -#else -# error No atomic decrement implementation for your platform! -#endif -} - -sys::cas_flag sys::AtomicAdd(volatile sys::cas_flag* ptr, sys::cas_flag val) { -#if LLVM_MULTITHREADED==0 - *ptr += val; - return *ptr; -#elif defined(__GNUC__) - return __sync_add_and_fetch(ptr, val); -#elif defined(_MSC_VER) - return InterlockedExchangeAdd(ptr, val) + val; -#else -# error No atomic add implementation for your platform! -#endif -} - -sys::cas_flag sys::AtomicMul(volatile sys::cas_flag* ptr, sys::cas_flag val) { - sys::cas_flag original, result; - do { - original = *ptr; - result = original * val; - } while (sys::CompareAndSwap(ptr, result, original) != original); - - return result; -} - -sys::cas_flag sys::AtomicDiv(volatile sys::cas_flag* ptr, sys::cas_flag val) { - sys::cas_flag original, result; - do { - original = *ptr; - result = original / val; - } while (sys::CompareAndSwap(ptr, result, original) != original); - - return result; -} diff --git a/lib/System/CMakeLists.txt b/lib/System/CMakeLists.txt deleted file mode 100644 index b43c3af..0000000 --- a/lib/System/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -add_llvm_library(LLVMSystem - Alarm.cpp - Atomic.cpp - Disassembler.cpp - DynamicLibrary.cpp - Errno.cpp - Host.cpp - IncludeFile.cpp - Memory.cpp - Mutex.cpp - Path.cpp - 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 - Unix/Mutex.inc - Unix/Path.inc - Unix/Process.inc - Unix/Program.inc - Unix/RWMutex.inc - Unix/Signals.inc - Unix/ThreadLocal.inc - Unix/TimeValue.inc - Win32/Alarm.inc - Win32/DynamicLibrary.inc - Win32/Host.inc - Win32/Memory.inc - Win32/Mutex.inc - Win32/Path.inc - Win32/Process.inc - Win32/Program.inc - Win32/RWMutex.inc - Win32/Signals.inc - Win32/ThreadLocal.inc - Win32/TimeValue.inc - ) - -if( BUILD_SHARED_LIBS AND NOT WIN32 ) - target_link_libraries(LLVMSystem ${CMAKE_DL_LIBS}) -endif() diff --git a/lib/System/Disassembler.cpp b/lib/System/Disassembler.cpp deleted file mode 100644 index 139e3be..0000000 --- a/lib/System/Disassembler.cpp +++ /dev/null @@ -1,75 +0,0 @@ -//===- lib/System/Disassembler.cpp ------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the necessary glue to call external disassembler -// libraries. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Config/config.h" -#include "llvm/System/Disassembler.h" - -#include <cassert> -#include <iomanip> -#include <string> -#include <sstream> - -#if USE_UDIS86 -#include <udis86.h> -#endif - -using namespace llvm; - -bool llvm::sys::hasDisassembler() -{ -#if defined (__i386__) || defined (__amd64__) || defined (__x86_64__) - // We have option to enable udis86 library. -# if USE_UDIS86 - return true; -#else - return false; -#endif -#else - return false; -#endif -} - -std::string llvm::sys::disassembleBuffer(uint8_t* start, size_t length, - uint64_t pc) { - std::stringstream res; - -#if (defined (__i386__) || defined (__amd64__) || defined (__x86_64__)) \ - && USE_UDIS86 - unsigned bits; -# if defined(__i386__) - bits = 32; -# else - bits = 64; -# endif - - ud_t ud_obj; - - ud_init(&ud_obj); - ud_set_input_buffer(&ud_obj, start, length); - ud_set_mode(&ud_obj, bits); - ud_set_pc(&ud_obj, pc); - ud_set_syntax(&ud_obj, UD_SYN_ATT); - - res << std::setbase(16) - << std::setw(bits/4); - - while (ud_disassemble(&ud_obj)) { - res << ud_insn_off(&ud_obj) << ":\t" << ud_insn_asm(&ud_obj) << "\n"; - } -#else - res << "No disassembler available. See configure help for options.\n"; -#endif - - return res.str(); -} diff --git a/lib/System/DynamicLibrary.cpp b/lib/System/DynamicLibrary.cpp deleted file mode 100644 index 660db49..0000000 --- a/lib/System/DynamicLibrary.cpp +++ /dev/null @@ -1,161 +0,0 @@ -//===-- DynamicLibrary.cpp - Runtime link/load libraries --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This header file implements the operating system DynamicLibrary concept. -// -// FIXME: This file leaks the ExplicitSymbols and OpenedHandles vector, and is -// not thread safe! -// -//===----------------------------------------------------------------------===// - -#include "llvm/System/DynamicLibrary.h" -#include "llvm/Config/config.h" -#include <cstdio> -#include <cstring> -#include <map> -#include <vector> - -// Collection of symbol name/value pairs to be searched prior to any libraries. -static std::map<std::string, void*> *ExplicitSymbols = 0; - -namespace { - -struct ExplicitSymbolsDeleter { - ~ExplicitSymbolsDeleter() { - if (ExplicitSymbols) - delete ExplicitSymbols; - } -}; - -} - -static ExplicitSymbolsDeleter Dummy; - -void llvm::sys::DynamicLibrary::AddSymbol(const char* symbolName, - void *symbolValue) { - if (ExplicitSymbols == 0) - ExplicitSymbols = new std::map<std::string, void*>(); - (*ExplicitSymbols)[symbolName] = symbolValue; -} - -#ifdef LLVM_ON_WIN32 - -#include "Win32/DynamicLibrary.inc" - -#else - -#if HAVE_DLFCN_H -#include <dlfcn.h> -using namespace llvm; -using namespace llvm::sys; - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only TRULY operating system -//=== independent code. -//===----------------------------------------------------------------------===// - -static std::vector<void *> *OpenedHandles = 0; - - -bool DynamicLibrary::LoadLibraryPermanently(const char *Filename, - std::string *ErrMsg) { - void *H = dlopen(Filename, RTLD_LAZY|RTLD_GLOBAL); - if (H == 0) { - if (ErrMsg) *ErrMsg = dlerror(); - return true; - } -#ifdef __CYGWIN__ - // Cygwin searches symbols only in the main - // with the handle of dlopen(NULL, RTLD_GLOBAL). - if (Filename == NULL) - H = RTLD_DEFAULT; -#endif - if (OpenedHandles == 0) - OpenedHandles = new std::vector<void *>(); - OpenedHandles->push_back(H); - return false; -} -#else - -using namespace llvm; -using namespace llvm::sys; - -bool DynamicLibrary::LoadLibraryPermanently(const char *Filename, - std::string *ErrMsg) { - if (ErrMsg) *ErrMsg = "dlopen() not supported on this platform"; - return true; -} -#endif - -namespace llvm { -void *SearchForAddressOfSpecialSymbol(const char* symbolName); -} - -void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { - // First check symbols added via AddSymbol(). - if (ExplicitSymbols) { - std::map<std::string, void *>::iterator I = - ExplicitSymbols->find(symbolName); - std::map<std::string, void *>::iterator E = ExplicitSymbols->end(); - - if (I != E) - return I->second; - } - -#if HAVE_DLFCN_H - // Now search the libraries. - if (OpenedHandles) { - for (std::vector<void *>::iterator I = OpenedHandles->begin(), - E = OpenedHandles->end(); I != E; ++I) { - //lt_ptr ptr = lt_dlsym(*I, symbolName); - void *ptr = dlsym(*I, symbolName); - if (ptr) { - return ptr; - } - } - } -#endif - - if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName)) - return Result; - -// This macro returns the address of a well-known, explicit symbol -#define EXPLICIT_SYMBOL(SYM) \ - if (!strcmp(symbolName, #SYM)) return &SYM - -// On linux we have a weird situation. The stderr/out/in symbols are both -// macros and global variables because of standards requirements. So, we -// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first. -#if defined(__linux__) - { - EXPLICIT_SYMBOL(stderr); - EXPLICIT_SYMBOL(stdout); - EXPLICIT_SYMBOL(stdin); - } -#else - // For everything else, we want to check to make sure the symbol isn't defined - // as a macro before using EXPLICIT_SYMBOL. - { -#ifndef stdin - EXPLICIT_SYMBOL(stdin); -#endif -#ifndef stdout - EXPLICIT_SYMBOL(stdout); -#endif -#ifndef stderr - EXPLICIT_SYMBOL(stderr); -#endif - } -#endif -#undef EXPLICIT_SYMBOL - - return 0; -} - -#endif // LLVM_ON_WIN32 diff --git a/lib/System/Errno.cpp b/lib/System/Errno.cpp deleted file mode 100644 index 68f66f6..0000000 --- a/lib/System/Errno.cpp +++ /dev/null @@ -1,74 +0,0 @@ -//===- Errno.cpp - errno support --------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the errno wrappers. -// -//===----------------------------------------------------------------------===// - -#include "llvm/System/Errno.h" -#include "llvm/Config/config.h" // Get autoconf configuration settings - -#if HAVE_STRING_H -#include <string.h> - -#if HAVE_ERRNO_H -#include <errno.h> -#endif - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only TRULY operating system -//=== independent code. -//===----------------------------------------------------------------------===// - -namespace llvm { -namespace sys { - -#if HAVE_ERRNO_H -std::string StrError() { - return StrError(errno); -} -#endif // HAVE_ERRNO_H - -std::string StrError(int errnum) { - const int MaxErrStrLen = 2000; - char buffer[MaxErrStrLen]; - buffer[0] = '\0'; - char* str = buffer; -#ifdef HAVE_STRERROR_R - // strerror_r is thread-safe. - if (errnum) -# if defined(__GLIBC__) && defined(_GNU_SOURCE) - // glibc defines its own incompatible version of strerror_r - // which may not use the buffer supplied. - str = strerror_r(errnum,buffer,MaxErrStrLen-1); -# else - strerror_r(errnum,buffer,MaxErrStrLen-1); -# endif -#elif defined(HAVE_STRERROR_S) // Windows. - if (errnum) - strerror_s(buffer, errnum); -#elif defined(HAVE_STRERROR) - // Copy the thread un-safe result of strerror into - // the buffer as fast as possible to minimize impact - // of collision of strerror in multiple threads. - if (errnum) - strncpy(buffer,strerror(errnum),MaxErrStrLen-1); - buffer[MaxErrStrLen-1] = '\0'; -#else - // Strange that this system doesn't even have strerror - // but, oh well, just use a generic message - sprintf(buffer, "Error #%d", errnum); -#endif - return str; -} - -} // namespace sys -} // namespace llvm - -#endif // HAVE_STRING_H diff --git a/lib/System/Host.cpp b/lib/System/Host.cpp deleted file mode 100644 index e7193db..0000000 --- a/lib/System/Host.cpp +++ /dev/null @@ -1,305 +0,0 @@ -//===-- Host.cpp - Implement OS Host Concept --------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This header file implements the operating system Host concept. -// -//===----------------------------------------------------------------------===// - -#include "llvm/System/Host.h" -#include "llvm/Config/config.h" -#include <string.h> - -// Include the platform-specific parts of this class. -#ifdef LLVM_ON_UNIX -#include "Unix/Host.inc" -#endif -#ifdef LLVM_ON_WIN32 -#include "Win32/Host.inc" -#endif -#ifdef _MSC_VER -#include <intrin.h> -#endif - -//===----------------------------------------------------------------------===// -// -// Implementations of the CPU detection routines -// -//===----------------------------------------------------------------------===// - -using namespace llvm; - -#if defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)\ - || defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64) - -/// GetX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in the -/// specified arguments. If we can't run cpuid on the host, return true. -static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX, - unsigned *rEBX, unsigned *rECX, unsigned *rEDX) { -#if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64) - #if defined(__GNUC__) - // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually. - asm ("movq\t%%rbx, %%rsi\n\t" - "cpuid\n\t" - "xchgq\t%%rbx, %%rsi\n\t" - : "=a" (*rEAX), - "=S" (*rEBX), - "=c" (*rECX), - "=d" (*rEDX) - : "a" (value)); - return false; - #elif defined(_MSC_VER) - int registers[4]; - __cpuid(registers, value); - *rEAX = registers[0]; - *rEBX = registers[1]; - *rECX = registers[2]; - *rEDX = registers[3]; - return false; - #endif -#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86) - #if defined(__GNUC__) - asm ("movl\t%%ebx, %%esi\n\t" - "cpuid\n\t" - "xchgl\t%%ebx, %%esi\n\t" - : "=a" (*rEAX), - "=S" (*rEBX), - "=c" (*rECX), - "=d" (*rEDX) - : "a" (value)); - return false; - #elif defined(_MSC_VER) - __asm { - mov eax,value - cpuid - mov esi,rEAX - mov dword ptr [esi],eax - mov esi,rEBX - mov dword ptr [esi],ebx - mov esi,rECX - mov dword ptr [esi],ecx - mov esi,rEDX - mov dword ptr [esi],edx - } - return false; - #endif -#endif - return true; -} - -static void DetectX86FamilyModel(unsigned EAX, unsigned &Family, unsigned &Model) { - Family = (EAX >> 8) & 0xf; // Bits 8 - 11 - Model = (EAX >> 4) & 0xf; // Bits 4 - 7 - if (Family == 6 || Family == 0xf) { - if (Family == 0xf) - // Examine extended family ID if family ID is F. - Family += (EAX >> 20) & 0xff; // Bits 20 - 27 - // Examine extended model ID if family ID is 6 or F. - Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19 - } -} - -std::string sys::getHostCPUName() { - unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; - if (GetX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX)) - return "generic"; - unsigned Family = 0; - unsigned Model = 0; - DetectX86FamilyModel(EAX, Family, Model); - - GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); - bool Em64T = (EDX >> 29) & 0x1; - bool HasSSE3 = (ECX & 0x1); - - union { - unsigned u[3]; - char c[12]; - } text; - - GetX86CpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1); - if (memcmp(text.c, "GenuineIntel", 12) == 0) { - switch (Family) { - case 3: - return "i386"; - case 4: - switch (Model) { - case 0: // Intel486TM DX processors - case 1: // Intel486TM DX processors - case 2: // Intel486 SX processors - case 3: // Intel487TM processors, IntelDX2 OverDrive® processors, - // IntelDX2TM processors - case 4: // Intel486 SL processor - case 5: // IntelSX2TM processors - case 7: // Write-Back Enhanced IntelDX2 processors - case 8: // IntelDX4 OverDrive processors, IntelDX4TM processors - default: return "i486"; - } - case 5: - switch (Model) { - case 1: // Pentium OverDrive processor for Pentium processor (60, 66), - // Pentium® processors (60, 66) - case 2: // Pentium OverDrive processor for Pentium processor (75, 90, - // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133, - // 150, 166, 200) - case 3: // Pentium OverDrive processors for Intel486 processor-based - // systems - return "pentium"; - - case 4: // Pentium OverDrive processor with MMXTM technology for Pentium - // processor (75, 90, 100, 120, 133), Pentium processor with - // MMXTM technology (166, 200) - return "pentium-mmx"; - - default: return "pentium"; - } - case 6: - switch (Model) { - case 1: // Pentium Pro processor - return "pentiumpro"; - - case 3: // Intel Pentium II OverDrive processor, Pentium II processor, - // model 03 - case 5: // Pentium II processor, model 05, Pentium II Xeon processor, - // model 05, and Intel® Celeron® processor, model 05 - case 6: // Celeron processor, model 06 - return "pentium2"; - - case 7: // Pentium III processor, model 07, and Pentium III Xeon - // processor, model 07 - case 8: // Pentium III processor, model 08, Pentium III Xeon processor, - // model 08, and Celeron processor, model 08 - case 10: // Pentium III Xeon processor, model 0Ah - case 11: // Pentium III processor, model 0Bh - return "pentium3"; - - case 9: // Intel Pentium M processor, Intel Celeron M processor model 09. - case 13: // Intel Pentium M processor, Intel Celeron M processor, model - // 0Dh. All processors are manufactured using the 90 nm process. - return "pentium-m"; - - case 14: // Intel CoreTM Duo processor, Intel CoreTM Solo processor, model - // 0Eh. All processors are manufactured using the 65 nm process. - return "yonah"; - - case 15: // Intel CoreTM2 Duo processor, Intel CoreTM2 Duo mobile - // processor, Intel CoreTM2 Quad processor, Intel CoreTM2 Quad - // mobile processor, Intel CoreTM2 Extreme processor, Intel - // Pentium Dual-Core processor, Intel Xeon processor, model - // 0Fh. All processors are manufactured using the 65 nm process. - case 22: // Intel Celeron processor model 16h. All processors are - // manufactured using the 65 nm process - return "core2"; - - case 21: // Intel EP80579 Integrated Processor and Intel EP80579 - // Integrated Processor with Intel QuickAssist Technology - return "i686"; // FIXME: ??? - - case 23: // Intel CoreTM2 Extreme processor, Intel Xeon processor, model - // 17h. All processors are manufactured using the 45 nm process. - // - // 45nm: Penryn , Wolfdale, Yorkfield (XE) - return "penryn"; - - case 26: // Intel Core i7 processor and Intel Xeon processor. All - // processors are manufactured using the 45 nm process. - case 29: // Intel Xeon processor MP. All processors are manufactured using - // the 45 nm process. - return "corei7"; - - case 28: // Intel Atom processor. All processors are manufactured using - // the 45 nm process - return "atom"; - - default: return "i686"; - } - case 15: { - switch (Model) { - case 0: // Pentium 4 processor, Intel Xeon processor. All processors are - // model 00h and manufactured using the 0.18 micron process. - case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon - // processor MP, and Intel Celeron processor. All processors are - // model 01h and manufactured using the 0.18 micron process. - case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor – M, - // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron - // processor, and Mobile Intel Celeron processor. All processors - // are model 02h and manufactured using the 0.13 micron process. - return (Em64T) ? "x86-64" : "pentium4"; - - case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D - // processor. All processors are model 03h and manufactured using - // the 90 nm process. - case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition, - // Pentium D processor, Intel Xeon processor, Intel Xeon - // processor MP, Intel Celeron D processor. All processors are - // model 04h and manufactured using the 90 nm process. - case 6: // Pentium 4 processor, Pentium D processor, Pentium processor - // Extreme Edition, Intel Xeon processor, Intel Xeon processor - // MP, Intel Celeron D processor. All processors are model 06h - // and manufactured using the 65 nm process. - return (Em64T) ? "nocona" : "prescott"; - - default: - return (Em64T) ? "x86-64" : "pentium4"; - } - } - - default: - return "generic"; - } - } else if (memcmp(text.c, "AuthenticAMD", 12) == 0) { - // FIXME: this poorly matches the generated SubtargetFeatureKV table. There - // appears to be no way to generate the wide variety of AMD-specific targets - // from the information returned from CPUID. - switch (Family) { - case 4: - return "i486"; - case 5: - switch (Model) { - case 6: - case 7: return "k6"; - case 8: return "k6-2"; - case 9: - case 13: return "k6-3"; - default: return "pentium"; - } - case 6: - switch (Model) { - case 4: return "athlon-tbird"; - case 6: - case 7: - case 8: return "athlon-mp"; - case 10: return "athlon-xp"; - default: return "athlon"; - } - case 15: - if (HasSSE3) { - return "k8-sse3"; - } else { - switch (Model) { - case 1: return "opteron"; - case 5: return "athlon-fx"; // also opteron - default: return "athlon64"; - } - } - case 16: - return "amdfam10"; - default: - return "generic"; - } - } - return "generic"; -} -#else -std::string sys::getHostCPUName() { - return "generic"; -} -#endif - -bool sys::getHostCPUFeatures(StringMap<bool> &Features){ - return false; -} diff --git a/lib/System/IncludeFile.cpp b/lib/System/IncludeFile.cpp deleted file mode 100644 index 8258d40..0000000 --- a/lib/System/IncludeFile.cpp +++ /dev/null @@ -1,20 +0,0 @@ -//===- lib/System/IncludeFile.cpp - Ensure Linking Of Implementation -----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the IncludeFile constructor. -// -//===----------------------------------------------------------------------===// - -#include "llvm/System/IncludeFile.h" - -using namespace llvm; - -// This constructor is used to ensure linking of other modules. See the -// llvm/System/IncludeFile.h header for details. -IncludeFile::IncludeFile(const void*) {} diff --git a/lib/System/Makefile b/lib/System/Makefile deleted file mode 100644 index bb013b9..0000000 --- a/lib/System/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -##===- lib/System/Makefile ---------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -LIBRARYNAME = LLVMSystem -BUILD_ARCHIVE = 1 -REQUIRES_RTTI = 1 -include $(LEVEL)/Makefile.config - -ifeq ($(HOST_OS),MingW) - REQUIRES_EH := 1 -endif - -EXTRA_DIST = Unix Win32 README.txt - -include $(LEVEL)/Makefile.common - -CompileCommonOpts := $(filter-out -pedantic,$(CompileCommonOpts)) -CompileCommonOpts := $(filter-out -Wno-long-long,$(CompileCommonOpts)) diff --git a/lib/System/Memory.cpp b/lib/System/Memory.cpp deleted file mode 100644 index ef23b8d..0000000 --- a/lib/System/Memory.cpp +++ /dev/null @@ -1,74 +0,0 @@ -//===- Memory.cpp - Memory Handling Support ---------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines some helpful functions for allocating memory and dealing -// with memory mapped files -// -//===----------------------------------------------------------------------===// - -#include "llvm/System/Memory.h" -#include "llvm/System/Valgrind.h" -#include "llvm/Config/config.h" - -namespace llvm { -using namespace sys; -} - -// Include the platform-specific parts of this class. -#ifdef LLVM_ON_UNIX -#include "Unix/Memory.inc" -#endif -#ifdef LLVM_ON_WIN32 -#include "Win32/Memory.inc" -#endif - -extern "C" void sys_icache_invalidate(const void *Addr, size_t len); - -/// InvalidateInstructionCache - Before the JIT can run a block of code -/// that has been emitted it must invalidate the instruction cache on some -/// platforms. -void llvm::sys::Memory::InvalidateInstructionCache(const void *Addr, - size_t Len) { - -// icache invalidation for PPC and ARM. -#if defined(__APPLE__) - -# if (defined(__POWERPC__) || defined (__ppc__) || \ - defined(_POWER) || defined(_ARCH_PPC)) || defined(__arm__) - sys_icache_invalidate(Addr, Len); -# endif - -#else - -# if (defined(__POWERPC__) || defined (__ppc__) || \ - defined(_POWER) || defined(_ARCH_PPC)) && defined(__GNUC__) - const size_t LineSize = 32; - - const intptr_t Mask = ~(LineSize - 1); - const intptr_t StartLine = ((intptr_t) Addr) & Mask; - const intptr_t EndLine = ((intptr_t) Addr + Len + LineSize - 1) & Mask; - - for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize) - asm volatile("dcbf 0, %0" : : "r"(Line)); - asm volatile("sync"); - - for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize) - asm volatile("icbi 0, %0" : : "r"(Line)); - asm volatile("isync"); -# elif defined(__arm__) && defined(__GNUC__) - // FIXME: Can we safely always call this for __GNUC__ everywhere? - char *Start = (char*) Addr; - char *End = Start + Len; - __clear_cache(Start, End); -# endif - -#endif // end apple - - ValgrindDiscardTranslations(Addr, Len); -} diff --git a/lib/System/Mutex.cpp b/lib/System/Mutex.cpp deleted file mode 100644 index 8ccd6e5..0000000 --- a/lib/System/Mutex.cpp +++ /dev/null @@ -1,157 +0,0 @@ -//===- Mutex.cpp - Mutual Exclusion Lock ------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the llvm::sys::Mutex class. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Config/config.h" -#include "llvm/System/Mutex.h" - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only TRULY operating system -//=== independent code. -//===----------------------------------------------------------------------===// - -#if !defined(ENABLE_THREADS) || ENABLE_THREADS == 0 -// Define all methods as no-ops if threading is explicitly disabled -namespace llvm { -using namespace sys; -MutexImpl::MutexImpl( bool recursive) { } -MutexImpl::~MutexImpl() { } -bool MutexImpl::acquire() { return true; } -bool MutexImpl::release() { return true; } -bool MutexImpl::tryacquire() { return true; } -} -#else - -#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK) - -#include <cassert> -#include <pthread.h> -#include <stdlib.h> - -namespace llvm { -using namespace sys; - - -// This variable is useful for situations where the pthread library has been -// compiled with weak linkage for its interface symbols. This allows the -// threading support to be turned off by simply not linking against -lpthread. -// In that situation, the value of pthread_mutex_init will be 0 and -// consequently pthread_enabled will be false. In such situations, all the -// pthread operations become no-ops and the functions all return false. If -// pthread_mutex_init does have an address, then mutex support is enabled. -// Note: all LLVM tools will link against -lpthread if its available since it -// is configured into the LIBS variable. -// Note: this line of code generates a warning if pthread_mutex_init is not -// declared with weak linkage. It's safe to ignore the warning. -static const bool pthread_enabled = true; - -// Construct a Mutex using pthread calls -MutexImpl::MutexImpl( bool recursive) - : data_(0) -{ - if (pthread_enabled) - { - // Declare the pthread_mutex data structures - pthread_mutex_t* mutex = - static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t))); - pthread_mutexattr_t attr; - - // Initialize the mutex attributes - int errorcode = pthread_mutexattr_init(&attr); - assert(errorcode == 0); - - // Initialize the mutex as a recursive mutex, if requested, or normal - // otherwise. - int kind = ( recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL ); - errorcode = pthread_mutexattr_settype(&attr, kind); - assert(errorcode == 0); - -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) - // Make it a process local mutex - errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE); -#endif - - // Initialize the mutex - errorcode = pthread_mutex_init(mutex, &attr); - assert(errorcode == 0); - - // Destroy the attributes - errorcode = pthread_mutexattr_destroy(&attr); - assert(errorcode == 0); - - // Assign the data member - data_ = mutex; - } -} - -// Destruct a Mutex -MutexImpl::~MutexImpl() -{ - if (pthread_enabled) - { - pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); - assert(mutex != 0); - pthread_mutex_destroy(mutex); - free(mutex); - } -} - -bool -MutexImpl::acquire() -{ - if (pthread_enabled) - { - pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); - assert(mutex != 0); - - int errorcode = pthread_mutex_lock(mutex); - return errorcode == 0; - } else return false; -} - -bool -MutexImpl::release() -{ - if (pthread_enabled) - { - pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); - assert(mutex != 0); - - int errorcode = pthread_mutex_unlock(mutex); - return errorcode == 0; - } else return false; -} - -bool -MutexImpl::tryacquire() -{ - if (pthread_enabled) - { - pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); - assert(mutex != 0); - - int errorcode = pthread_mutex_trylock(mutex); - return errorcode == 0; - } else return false; -} - -} - -#elif defined(LLVM_ON_UNIX) -#include "Unix/Mutex.inc" -#elif defined( LLVM_ON_WIN32) -#include "Win32/Mutex.inc" -#else -#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp -#endif -#endif - diff --git a/lib/System/Path.cpp b/lib/System/Path.cpp deleted file mode 100644 index 4445c66..0000000 --- a/lib/System/Path.cpp +++ /dev/null @@ -1,264 +0,0 @@ -//===-- Path.cpp - Implement OS Path Concept --------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This header file implements the operating system Path concept. -// -//===----------------------------------------------------------------------===// - -#include "llvm/System/Path.h" -#include "llvm/Config/config.h" -#include <cassert> -#include <cstring> -#include <ostream> -using namespace llvm; -using namespace sys; - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only TRULY operating system -//=== independent code. -//===----------------------------------------------------------------------===// - -bool Path::operator==(const Path &that) const { - return path == that.path; -} - -bool Path::operator<(const Path& that) const { - return path < that.path; -} - -Path -Path::GetLLVMConfigDir() { - Path result; -#ifdef LLVM_ETCDIR - if (result.set(LLVM_ETCDIR)) - return result; -#endif - return GetLLVMDefaultConfigDir(); -} - -LLVMFileType -sys::IdentifyFileType(const char *magic, unsigned length) { - assert(magic && "Invalid magic number string"); - assert(length >=4 && "Invalid magic number length"); - switch ((unsigned char)magic[0]) { - case 0xDE: // 0x0B17C0DE = BC wraper - if (magic[1] == (char)0xC0 && magic[2] == (char)0x17 && - magic[3] == (char)0x0B) - return Bitcode_FileType; - break; - case 'B': - if (magic[1] == 'C' && magic[2] == (char)0xC0 && magic[3] == (char)0xDE) - return Bitcode_FileType; - break; - case '!': - if (length >= 8) - if (memcmp(magic,"!<arch>\n",8) == 0) - return Archive_FileType; - break; - - case '\177': - if (magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F') { - if (length >= 18 && magic[17] == 0) - switch (magic[16]) { - default: break; - case 1: return ELF_Relocatable_FileType; - case 2: return ELF_Executable_FileType; - case 3: return ELF_SharedObject_FileType; - case 4: return ELF_Core_FileType; - } - } - break; - - case 0xCA: - if (magic[1] == char(0xFE) && magic[2] == char(0xBA) && - magic[3] == char(0xBE)) { - // This is complicated by an overlap with Java class files. - // See the Mach-O section in /usr/share/file/magic for details. - if (length >= 8 && magic[7] < 43) - // FIXME: Universal Binary of any type. - return Mach_O_DynamicallyLinkedSharedLib_FileType; - } - break; - - case 0xFE: - case 0xCE: { - uint16_t type = 0; - if (magic[0] == char(0xFE) && magic[1] == char(0xED) && - magic[2] == char(0xFA) && magic[3] == char(0xCE)) { - /* Native endian */ - if (length >= 16) type = magic[14] << 8 | magic[15]; - } else if (magic[0] == char(0xCE) && magic[1] == char(0xFA) && - magic[2] == char(0xED) && magic[3] == char(0xFE)) { - /* Reverse endian */ - if (length >= 14) type = magic[13] << 8 | magic[12]; - } - switch (type) { - default: break; - case 1: return Mach_O_Object_FileType; - case 2: return Mach_O_Executable_FileType; - case 3: return Mach_O_FixedVirtualMemorySharedLib_FileType; - case 4: return Mach_O_Core_FileType; - case 5: return Mach_O_PreloadExectuable_FileType; - case 6: return Mach_O_DynamicallyLinkedSharedLib_FileType; - case 7: return Mach_O_DynamicLinker_FileType; - case 8: return Mach_O_Bundle_FileType; - case 9: return Mach_O_DynamicallyLinkedSharedLibStub_FileType; - case 10: break; // FIXME: MH_DSYM companion file with only debug. - } - break; - } - case 0xF0: // PowerPC Windows - case 0x83: // Alpha 32-bit - case 0x84: // Alpha 64-bit - case 0x66: // MPS R4000 Windows - case 0x50: // mc68K - case 0x4c: // 80386 Windows - if (magic[1] == 0x01) - return COFF_FileType; - - case 0x90: // PA-RISC Windows - case 0x68: // mc68K Windows - if (magic[1] == 0x02) - return COFF_FileType; - break; - - default: - break; - } - return Unknown_FileType; -} - -bool -Path::isArchive() const { - return hasMagicNumber("!<arch>\012"); -} - -bool -Path::isDynamicLibrary() const { - std::string Magic; - if (getMagicNumber(Magic, 64)) - switch (IdentifyFileType(Magic.c_str(), - static_cast<unsigned>(Magic.length()))) { - default: return false; - case Mach_O_FixedVirtualMemorySharedLib_FileType: - case Mach_O_DynamicallyLinkedSharedLib_FileType: - case Mach_O_DynamicallyLinkedSharedLibStub_FileType: - case ELF_SharedObject_FileType: - case COFF_FileType: return true; - } - - return false; -} - -Path -Path::FindLibrary(std::string& name) { - std::vector<sys::Path> LibPaths; - GetSystemLibraryPaths(LibPaths); - for (unsigned i = 0; i < LibPaths.size(); ++i) { - sys::Path FullPath(LibPaths[i]); - FullPath.appendComponent("lib" + name + LTDL_SHLIB_EXT); - if (FullPath.isDynamicLibrary()) - return FullPath; - FullPath.eraseSuffix(); - FullPath.appendSuffix("a"); - if (FullPath.isArchive()) - return FullPath; - } - return sys::Path(); -} - -StringRef Path::GetDLLSuffix() { - return LTDL_SHLIB_EXT; -} - -bool -Path::isBitcodeFile() const { - std::string actualMagic; - if (!getMagicNumber(actualMagic, 4)) - return false; - LLVMFileType FT = - IdentifyFileType(actualMagic.c_str(), - static_cast<unsigned>(actualMagic.length())); - return FT == Bitcode_FileType; -} - -bool Path::hasMagicNumber(StringRef Magic) const { - std::string actualMagic; - if (getMagicNumber(actualMagic, static_cast<unsigned>(Magic.size()))) - return Magic == actualMagic; - return false; -} - -static void getPathList(const char*path, std::vector<Path>& Paths) { - const char* at = path; - const char* delim = strchr(at, PathSeparator); - Path tmpPath; - while (delim != 0) { - std::string tmp(at, size_t(delim-at)); - if (tmpPath.set(tmp)) - if (tmpPath.canRead()) - Paths.push_back(tmpPath); - at = delim + 1; - delim = strchr(at, PathSeparator); - } - - if (*at != 0) - if (tmpPath.set(std::string(at))) - if (tmpPath.canRead()) - Paths.push_back(tmpPath); -} - -static StringRef getDirnameCharSep(StringRef path, const char *Sep) { - assert(Sep[0] != '\0' && Sep[1] == '\0' && - "Sep must be a 1-character string literal."); - if (path.empty()) - return "."; - - // If the path is all slashes, return a single slash. - // Otherwise, remove all trailing slashes. - - signed pos = static_cast<signed>(path.size()) - 1; - - while (pos >= 0 && path[pos] == Sep[0]) - --pos; - - if (pos < 0) - return path[0] == Sep[0] ? Sep : "."; - - // Any slashes left? - signed i = 0; - - while (i < pos && path[i] != Sep[0]) - ++i; - - if (i == pos) // No slashes? Return "." - return "."; - - // There is at least one slash left. Remove all trailing non-slashes. - while (pos >= 0 && path[pos] != Sep[0]) - --pos; - - // Remove any trailing slashes. - while (pos >= 0 && path[pos] == Sep[0]) - --pos; - - if (pos < 0) - return path[0] == Sep[0] ? Sep : "."; - - return path.substr(0, pos+1); -} - -// Include the truly platform-specific parts of this class. -#if defined(LLVM_ON_UNIX) -#include "Unix/Path.inc" -#endif -#if defined(LLVM_ON_WIN32) -#include "Win32/Path.inc" -#endif - diff --git a/lib/System/Process.cpp b/lib/System/Process.cpp deleted file mode 100644 index e93b2af..0000000 --- a/lib/System/Process.cpp +++ /dev/null @@ -1,33 +0,0 @@ -//===-- Process.cpp - Implement OS Process Concept --------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This header file implements the operating system Process concept. -// -//===----------------------------------------------------------------------===// - -#include "llvm/System/Process.h" -#include "llvm/Config/config.h" - -namespace llvm { -using namespace sys; - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only TRULY operating system -//=== independent code. -//===----------------------------------------------------------------------===// - -} - -// Include the platform-specific parts of this class. -#ifdef LLVM_ON_UNIX -#include "Unix/Process.inc" -#endif -#ifdef LLVM_ON_WIN32 -#include "Win32/Process.inc" -#endif diff --git a/lib/System/Program.cpp b/lib/System/Program.cpp deleted file mode 100644 index cd58c2c..0000000 --- a/lib/System/Program.cpp +++ /dev/null @@ -1,56 +0,0 @@ -//===-- Program.cpp - Implement OS Program Concept --------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This header file implements the operating system Program concept. -// -//===----------------------------------------------------------------------===// - -#include "llvm/System/Program.h" -#include "llvm/Config/config.h" -using namespace llvm; -using namespace sys; - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only TRULY operating system -//=== independent code. -//===----------------------------------------------------------------------===// - -int -Program::ExecuteAndWait(const Path& path, - const char** args, - const char** envp, - const Path** redirects, - unsigned secondsToWait, - unsigned memoryLimit, - std::string* ErrMsg) { - Program prg; - if (prg.Execute(path, args, envp, redirects, memoryLimit, ErrMsg)) - return prg.Wait(secondsToWait, ErrMsg); - else - return -1; -} - -void -Program::ExecuteNoWait(const Path& path, - const char** args, - const char** envp, - const Path** redirects, - unsigned memoryLimit, - std::string* ErrMsg) { - Program prg; - prg.Execute(path, args, envp, redirects, memoryLimit, ErrMsg); -} - -// Include the platform-specific parts of this class. -#ifdef LLVM_ON_UNIX -#include "Unix/Program.inc" -#endif -#ifdef LLVM_ON_WIN32 -#include "Win32/Program.inc" -#endif diff --git a/lib/System/README.txt b/lib/System/README.txt deleted file mode 100644 index eacb200..0000000 --- a/lib/System/README.txt +++ /dev/null @@ -1,43 +0,0 @@ -Design Of lib/System -==================== - -The software in this directory is designed to completely shield LLVM from any -and all operating system specific functionality. It is not intended to be a -complete operating system wrapper (such as ACE), but only to provide the -functionality necessary to support LLVM. - -The software located here, of necessity, has very specific and stringent design -rules. Violation of these rules means that cracks in the shield could form and -the primary goal of the library is defeated. By consistently using this library, -LLVM becomes more easily ported to new platforms since the only thing requiring -porting is this library. - -Complete documentation for the library can be found in the file: - llvm/docs/SystemLibrary.html -or at this URL: - http://llvm.org/docs/SystemLibrary.html - -While we recommend that you read the more detailed documentation, for the -impatient, here's a high level summary of the library's requirements. - - 1. No system header files are to be exposed through the interface. - 2. Std C++ and Std C header files are okay to be exposed through the interface. - 3. No exposed system-specific functions. - 4. No exposed system-specific data. - 5. Data in lib/System classes must use only simple C++ intrinsic types. - 6. Errors are handled by returning "true" and setting an optional std::string - 7. Library must not throw any exceptions, period. - 8. Interface functions must not have throw() specifications. - 9. No duplicate function impementations are permitted within an operating - system class. - -To accomplish these requirements, the library has numerous design criteria that -must be satisfied. Here's a high level summary of the library's design criteria: - - 1. No unused functionality (only what LLVM needs) - 2. High-Level Interfaces - 3. Use Opaque Classes - 4. Common Implementations</a></li> - 5. Multiple Implementations</a></li> - 6. Minimize Memory Allocation</a></li> - 7. No Virtual Methods diff --git a/lib/System/RWMutex.cpp b/lib/System/RWMutex.cpp deleted file mode 100644 index deb0470..0000000 --- a/lib/System/RWMutex.cpp +++ /dev/null @@ -1,157 +0,0 @@ -//===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the llvm::sys::RWMutex class. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Config/config.h" -#include "llvm/System/RWMutex.h" -#include <cstring> - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only TRULY operating system -//=== independent code. -//===----------------------------------------------------------------------===// - -#if !defined(ENABLE_THREADS) || ENABLE_THREADS == 0 -// Define all methods as no-ops if threading is explicitly disabled -namespace llvm { -using namespace sys; -RWMutexImpl::RWMutexImpl() { } -RWMutexImpl::~RWMutexImpl() { } -bool RWMutexImpl::reader_acquire() { return true; } -bool RWMutexImpl::reader_release() { return true; } -bool RWMutexImpl::writer_acquire() { return true; } -bool RWMutexImpl::writer_release() { return true; } -} -#else - -#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT) - -#include <cassert> -#include <pthread.h> -#include <stdlib.h> - -namespace llvm { -using namespace sys; - - -// This variable is useful for situations where the pthread library has been -// compiled with weak linkage for its interface symbols. This allows the -// threading support to be turned off by simply not linking against -lpthread. -// In that situation, the value of pthread_mutex_init will be 0 and -// consequently pthread_enabled will be false. In such situations, all the -// pthread operations become no-ops and the functions all return false. If -// pthread_rwlock_init does have an address, then rwlock support is enabled. -// Note: all LLVM tools will link against -lpthread if its available since it -// is configured into the LIBS variable. -// Note: this line of code generates a warning if pthread_rwlock_init is not -// declared with weak linkage. It's safe to ignore the warning. -static const bool pthread_enabled = true; - -// Construct a RWMutex using pthread calls -RWMutexImpl::RWMutexImpl() - : data_(0) -{ - if (pthread_enabled) - { - // Declare the pthread_rwlock data structures - pthread_rwlock_t* rwlock = - static_cast<pthread_rwlock_t*>(malloc(sizeof(pthread_rwlock_t))); - -#ifdef __APPLE__ - // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init. - bzero(rwlock, sizeof(pthread_rwlock_t)); -#endif - - // Initialize the rwlock - int errorcode = pthread_rwlock_init(rwlock, NULL); - (void)errorcode; - assert(errorcode == 0); - - // Assign the data member - data_ = rwlock; - } -} - -// Destruct a RWMutex -RWMutexImpl::~RWMutexImpl() -{ - if (pthread_enabled) - { - pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); - assert(rwlock != 0); - pthread_rwlock_destroy(rwlock); - free(rwlock); - } -} - -bool -RWMutexImpl::reader_acquire() -{ - if (pthread_enabled) - { - pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); - assert(rwlock != 0); - - int errorcode = pthread_rwlock_rdlock(rwlock); - return errorcode == 0; - } else return false; -} - -bool -RWMutexImpl::reader_release() -{ - if (pthread_enabled) - { - pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); - assert(rwlock != 0); - - int errorcode = pthread_rwlock_unlock(rwlock); - return errorcode == 0; - } else return false; -} - -bool -RWMutexImpl::writer_acquire() -{ - if (pthread_enabled) - { - pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); - assert(rwlock != 0); - - int errorcode = pthread_rwlock_wrlock(rwlock); - return errorcode == 0; - } else return false; -} - -bool -RWMutexImpl::writer_release() -{ - if (pthread_enabled) - { - pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); - assert(rwlock != 0); - - int errorcode = pthread_rwlock_unlock(rwlock); - return errorcode == 0; - } else return false; -} - -} - -#elif defined(LLVM_ON_UNIX) -#include "Unix/RWMutex.inc" -#elif defined( LLVM_ON_WIN32) -#include "Win32/RWMutex.inc" -#else -#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp -#endif -#endif diff --git a/lib/System/SearchForAddressOfSpecialSymbol.cpp b/lib/System/SearchForAddressOfSpecialSymbol.cpp deleted file mode 100644 index 73b484c..0000000 --- a/lib/System/SearchForAddressOfSpecialSymbol.cpp +++ /dev/null @@ -1,64 +0,0 @@ -//===- 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/Signals.cpp b/lib/System/Signals.cpp deleted file mode 100644 index d345b0a..0000000 --- a/lib/System/Signals.cpp +++ /dev/null @@ -1,34 +0,0 @@ -//===- Signals.cpp - Signal Handling support --------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines some helpful functions for dealing with the possibility of -// Unix signals occuring while your program is running. -// -//===----------------------------------------------------------------------===// - -#include "llvm/System/Signals.h" -#include "llvm/Config/config.h" - -namespace llvm { -using namespace sys; - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only TRULY operating system -//=== independent code. -//===----------------------------------------------------------------------===// - -} - -// Include the platform-specific parts of this class. -#ifdef LLVM_ON_UNIX -#include "Unix/Signals.inc" -#endif -#ifdef LLVM_ON_WIN32 -#include "Win32/Signals.inc" -#endif diff --git a/lib/System/ThreadLocal.cpp b/lib/System/ThreadLocal.cpp deleted file mode 100644 index f6a55a1..0000000 --- a/lib/System/ThreadLocal.cpp +++ /dev/null @@ -1,85 +0,0 @@ -//===- ThreadLocal.cpp - Thread Local Data ----------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the llvm::sys::ThreadLocal class. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Config/config.h" -#include "llvm/System/ThreadLocal.h" - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only TRULY operating system -//=== independent code. -//===----------------------------------------------------------------------===// - -#if !defined(ENABLE_THREADS) || ENABLE_THREADS == 0 -// Define all methods as no-ops if threading is explicitly disabled -namespace llvm { -using namespace sys; -ThreadLocalImpl::ThreadLocalImpl() { } -ThreadLocalImpl::~ThreadLocalImpl() { } -void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);} -const void* ThreadLocalImpl::getInstance() { return data; } -void ThreadLocalImpl::removeInstance() { data = 0; } -} -#else - -#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC) - -#include <cassert> -#include <pthread.h> -#include <stdlib.h> - -namespace llvm { -using namespace sys; - -ThreadLocalImpl::ThreadLocalImpl() : data(0) { - pthread_key_t* key = new pthread_key_t; - int errorcode = pthread_key_create(key, NULL); - assert(errorcode == 0); - (void) errorcode; - data = (void*)key; -} - -ThreadLocalImpl::~ThreadLocalImpl() { - pthread_key_t* key = static_cast<pthread_key_t*>(data); - int errorcode = pthread_key_delete(*key); - assert(errorcode == 0); - (void) errorcode; - delete key; -} - -void ThreadLocalImpl::setInstance(const void* d) { - pthread_key_t* key = static_cast<pthread_key_t*>(data); - int errorcode = pthread_setspecific(*key, d); - assert(errorcode == 0); - (void) errorcode; -} - -const void* ThreadLocalImpl::getInstance() { - pthread_key_t* key = static_cast<pthread_key_t*>(data); - return pthread_getspecific(*key); -} - -void ThreadLocalImpl::removeInstance() { - setInstance(0); -} - -} - -#elif defined(LLVM_ON_UNIX) -#include "Unix/ThreadLocal.inc" -#elif defined( LLVM_ON_WIN32) -#include "Win32/ThreadLocal.inc" -#else -#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/ThreadLocal.cpp -#endif -#endif - diff --git a/lib/System/Threading.cpp b/lib/System/Threading.cpp deleted file mode 100644 index 466c468..0000000 --- a/lib/System/Threading.cpp +++ /dev/null @@ -1,64 +0,0 @@ -//===-- llvm/System/Threading.cpp- Control multithreading mode --*- C++ -*-==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements llvm_start_multithreaded() and friends. -// -//===----------------------------------------------------------------------===// - -#include "llvm/System/Threading.h" -#include "llvm/System/Atomic.h" -#include "llvm/System/Mutex.h" -#include "llvm/Config/config.h" -#include <cassert> - -using namespace llvm; - -static bool multithreaded_mode = false; - -static sys::Mutex* global_lock = 0; - -bool llvm::llvm_start_multithreaded() { -#ifdef LLVM_MULTITHREADED - assert(!multithreaded_mode && "Already multithreaded!"); - multithreaded_mode = true; - global_lock = new sys::Mutex(true); - - // We fence here to ensure that all initialization is complete BEFORE we - // return from llvm_start_multithreaded(). - sys::MemoryFence(); - return true; -#else - return false; -#endif -} - -void llvm::llvm_stop_multithreaded() { -#ifdef LLVM_MULTITHREADED - assert(multithreaded_mode && "Not currently multithreaded!"); - - // We fence here to insure that all threaded operations are complete BEFORE we - // return from llvm_stop_multithreaded(). - sys::MemoryFence(); - - multithreaded_mode = false; - delete global_lock; -#endif -} - -bool llvm::llvm_is_multithreaded() { - return multithreaded_mode; -} - -void llvm::llvm_acquire_global_lock() { - if (multithreaded_mode) global_lock->acquire(); -} - -void llvm::llvm_release_global_lock() { - if (multithreaded_mode) global_lock->release(); -} diff --git a/lib/System/TimeValue.cpp b/lib/System/TimeValue.cpp deleted file mode 100644 index cf4984c..0000000 --- a/lib/System/TimeValue.cpp +++ /dev/null @@ -1,58 +0,0 @@ -//===-- TimeValue.cpp - Implement OS TimeValue Concept ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the operating system TimeValue concept. -// -//===----------------------------------------------------------------------===// - -#include "llvm/System/TimeValue.h" -#include "llvm/Config/config.h" - -namespace llvm { -using namespace sys; - -const TimeValue TimeValue::MinTime = TimeValue ( INT64_MIN,0 ); -const TimeValue TimeValue::MaxTime = TimeValue ( INT64_MAX,0 ); -const TimeValue TimeValue::ZeroTime = TimeValue ( 0,0 ); -const TimeValue TimeValue::PosixZeroTime = TimeValue ( -946684800,0 ); -const TimeValue TimeValue::Win32ZeroTime = TimeValue ( -12591158400ULL,0 ); - -void -TimeValue::normalize( void ) { - if ( nanos_ >= NANOSECONDS_PER_SECOND ) { - do { - seconds_++; - nanos_ -= NANOSECONDS_PER_SECOND; - } while ( nanos_ >= NANOSECONDS_PER_SECOND ); - } else if (nanos_ <= -NANOSECONDS_PER_SECOND ) { - do { - seconds_--; - nanos_ += NANOSECONDS_PER_SECOND; - } while (nanos_ <= -NANOSECONDS_PER_SECOND); - } - - if (seconds_ >= 1 && nanos_ < 0) { - seconds_--; - nanos_ += NANOSECONDS_PER_SECOND; - } else if (seconds_ < 0 && nanos_ > 0) { - seconds_++; - nanos_ -= NANOSECONDS_PER_SECOND; - } -} - -} - -/// Include the platform specific portion of TimeValue class -#ifdef LLVM_ON_UNIX -#include "Unix/TimeValue.inc" -#endif -#ifdef LLVM_ON_WIN32 -#include "Win32/TimeValue.inc" -#endif - diff --git a/lib/System/Unix/Alarm.inc b/lib/System/Unix/Alarm.inc deleted file mode 100644 index fb42b6c..0000000 --- a/lib/System/Unix/Alarm.inc +++ /dev/null @@ -1,72 +0,0 @@ -//===-- Alarm.inc - Implement Unix Alarm Support ----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the UNIX Alarm support. -// -//===----------------------------------------------------------------------===// - -#include <signal.h> -#include <unistd.h> -#include <cassert> -using namespace llvm; - -/// AlarmCancelled - This flag is set by the SIGINT signal handler if the -/// user presses CTRL-C. -static volatile bool AlarmCancelled = false; - -/// AlarmTriggered - This flag is set by the SIGALRM signal handler if the -/// alarm was triggered. -static volatile bool AlarmTriggered = false; - -/// NestedSOI - Sanity check. Alarms cannot be nested or run in parallel. -/// This ensures that they never do. -static bool NestedSOI = false; - -static RETSIGTYPE SigIntHandler(int Sig) { - AlarmCancelled = true; - signal(SIGINT, SigIntHandler); -} - -static RETSIGTYPE SigAlarmHandler(int Sig) { - AlarmTriggered = true; -} - -static void (*OldSigIntHandler) (int); - -void sys::SetupAlarm(unsigned seconds) { - assert(!NestedSOI && "sys::SetupAlarm calls cannot be nested!"); - NestedSOI = true; - AlarmCancelled = false; - AlarmTriggered = false; - ::signal(SIGALRM, SigAlarmHandler); - OldSigIntHandler = ::signal(SIGINT, SigIntHandler); - ::alarm(seconds); -} - -void sys::TerminateAlarm() { - assert(NestedSOI && "sys::TerminateAlarm called without sys::SetupAlarm!"); - ::alarm(0); - ::signal(SIGALRM, SIG_DFL); - ::signal(SIGINT, OldSigIntHandler); - AlarmCancelled = false; - AlarmTriggered = false; - NestedSOI = false; -} - -int sys::AlarmStatus() { - if (AlarmCancelled) - return -1; - if (AlarmTriggered) - return 1; - return 0; -} - -void sys::Sleep(unsigned n) { - ::sleep(n); -} diff --git a/lib/System/Unix/Host.inc b/lib/System/Unix/Host.inc deleted file mode 100644 index c76d6a4..0000000 --- a/lib/System/Unix/Host.inc +++ /dev/null @@ -1,96 +0,0 @@ - //===- llvm/System/Unix/Host.inc -------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the UNIX Host support. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic UNIX code that -//=== is guaranteed to work on *all* UNIX variants. -//===----------------------------------------------------------------------===// - -#include "llvm/Config/config.h" -#include "llvm/ADT/StringRef.h" -#include "Unix.h" -#include <sys/utsname.h> -#include <string> - -using namespace llvm; - -static std::string getOSVersion() { - struct utsname info; - - if (uname(&info)) - return ""; - - return info.release; -} - -std::string sys::getHostTriple() { - // FIXME: Derive directly instead of relying on the autoconf generated - // variable. - - StringRef HostTripleString(LLVM_HOSTTRIPLE); - std::pair<StringRef, StringRef> ArchSplit = HostTripleString.split('-'); - - // Normalize the arch, since the host triple may not actually match the host. - std::string Arch = ArchSplit.first; - - // It would be nice to do this in terms of llvm::Triple, but that is in - // Support which is layered above us. -#if defined(__x86_64__) - Arch = "x86_64"; -#elif defined(__i386__) - Arch = "i386"; -#elif defined(__ppc64__) - Arch = "powerpc64"; -#elif defined(__ppc__) - Arch = "powerpc"; -#elif defined(__arm__) - - // FIXME: We need to pick the right ARM triple (which involves querying the - // chip). However, for now this is most important for LLVM arch selection, so - // we only need to make sure to distinguish ARM and Thumb. -# if defined(__thumb__) - Arch = "thumb"; -# else - Arch = "arm"; -# endif - -#else - - // FIXME: When enough auto-detection is in place, this should just - // #error. Then at least the arch selection is done, and we only need the OS - // etc selection to kill off the use of LLVM_HOSTTRIPLE. - -#endif - - std::string Triple(Arch); - Triple += '-'; - Triple += ArchSplit.second; - - // Force i<N>86 to i386. - if (Triple[0] == 'i' && isdigit(Triple[1]) && - Triple[2] == '8' && Triple[3] == '6') - Triple[1] = '3'; - - // On darwin, we want to update the version to match that of the - // host. - std::string::size_type DarwinDashIdx = Triple.find("-darwin"); - if (DarwinDashIdx != std::string::npos) { - Triple.resize(DarwinDashIdx + strlen("-darwin")); - - // Only add the major part of the os version. - std::string Version = getOSVersion(); - Triple += Version.substr(0, Version.find('.')); - } - - return Triple; -} diff --git a/lib/System/Unix/Memory.inc b/lib/System/Unix/Memory.inc deleted file mode 100644 index 1b038f9..0000000 --- a/lib/System/Unix/Memory.inc +++ /dev/null @@ -1,151 +0,0 @@ -//===- Unix/Memory.cpp - Generic UNIX System Configuration ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines some functions for various memory management utilities. -// -//===----------------------------------------------------------------------===// - -#include "Unix.h" -#include "llvm/System/DataTypes.h" -#include "llvm/System/Process.h" - -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif - -#ifdef __APPLE__ -#include <mach/mach.h> -#endif - -/// AllocateRWX - Allocate a slab of memory with read/write/execute -/// permissions. This is typically used for JIT applications where we want -/// to emit code to the memory then jump to it. Getting this type of memory -/// is very OS specific. -/// -llvm::sys::MemoryBlock -llvm::sys::Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock, - std::string *ErrMsg) { - if (NumBytes == 0) return MemoryBlock(); - - size_t pageSize = Process::GetPageSize(); - size_t NumPages = (NumBytes+pageSize-1)/pageSize; - - int fd = -1; -#ifdef NEED_DEV_ZERO_FOR_MMAP - static int zero_fd = open("/dev/zero", O_RDWR); - if (zero_fd == -1) { - MakeErrMsg(ErrMsg, "Can't open /dev/zero device"); - return MemoryBlock(); - } - fd = zero_fd; -#endif - - int flags = MAP_PRIVATE | -#ifdef HAVE_MMAP_ANONYMOUS - MAP_ANONYMOUS -#else - MAP_ANON -#endif - ; - - void* start = NearBlock ? (unsigned char*)NearBlock->base() + - NearBlock->size() : 0; - -#if defined(__APPLE__) && defined(__arm__) - void *pa = ::mmap(start, pageSize*NumPages, PROT_READ|PROT_EXEC, - flags, fd, 0); -#else - void *pa = ::mmap(start, pageSize*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC, - flags, fd, 0); -#endif - if (pa == MAP_FAILED) { - if (NearBlock) //Try again without a near hint - return AllocateRWX(NumBytes, 0); - - MakeErrMsg(ErrMsg, "Can't allocate RWX Memory"); - return MemoryBlock(); - } - -#if defined(__APPLE__) && defined(__arm__) - kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)pa, - (vm_size_t)(pageSize*NumPages), 0, - VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY); - if (KERN_SUCCESS != kr) { - MakeErrMsg(ErrMsg, "vm_protect max RX failed"); - return sys::MemoryBlock(); - } - - kr = vm_protect(mach_task_self(), (vm_address_t)pa, - (vm_size_t)(pageSize*NumPages), 0, - VM_PROT_READ | VM_PROT_WRITE); - if (KERN_SUCCESS != kr) { - MakeErrMsg(ErrMsg, "vm_protect RW failed"); - return sys::MemoryBlock(); - } -#endif - - MemoryBlock result; - result.Address = pa; - result.Size = NumPages*pageSize; - - return result; -} - -bool llvm::sys::Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) { - if (M.Address == 0 || M.Size == 0) return false; - if (0 != ::munmap(M.Address, M.Size)) - return MakeErrMsg(ErrMsg, "Can't release RWX Memory"); - return false; -} - -bool llvm::sys::Memory::setWritable (MemoryBlock &M, std::string *ErrMsg) { -#if defined(__APPLE__) && defined(__arm__) - if (M.Address == 0 || M.Size == 0) return false; - sys::Memory::InvalidateInstructionCache(M.Address, M.Size); - kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address, - (vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_WRITE); - return KERN_SUCCESS == kr; -#else - return true; -#endif -} - -bool llvm::sys::Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) { -#if defined(__APPLE__) && defined(__arm__) - if (M.Address == 0 || M.Size == 0) return false; - sys::Memory::InvalidateInstructionCache(M.Address, M.Size); - kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address, - (vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY); - return KERN_SUCCESS == kr; -#else - return false; -#endif -} - -bool llvm::sys::Memory::setRangeWritable(const void *Addr, size_t Size) { -#if defined(__APPLE__) && defined(__arm__) - kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr, - (vm_size_t)Size, 0, - VM_PROT_READ | VM_PROT_WRITE); - return KERN_SUCCESS == kr; -#else - return true; -#endif -} - -bool llvm::sys::Memory::setRangeExecutable(const void *Addr, size_t Size) { -#if defined(__APPLE__) && defined(__arm__) - kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr, - (vm_size_t)Size, 0, - VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY); - return KERN_SUCCESS == kr; -#else - return true; -#endif -} diff --git a/lib/System/Unix/Mutex.inc b/lib/System/Unix/Mutex.inc deleted file mode 100644 index 4a5e28d..0000000 --- a/lib/System/Unix/Mutex.inc +++ /dev/null @@ -1,43 +0,0 @@ -//===- llvm/System/Unix/Mutex.inc - Unix Mutex Implementation ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Unix specific (non-pthread) Mutex class. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic UNIX code that -//=== is guaranteed to work on *all* UNIX variants. -//===----------------------------------------------------------------------===// - -namespace llvm -{ -using namespace sys; - -MutexImpl::MutexImpl( bool recursive) -{ -} - -MutexImpl::~MutexImpl() -{ -} - -bool -MutexImpl::release() -{ - return true; -} - -bool -MutexImpl::tryacquire( void ) -{ - return true; -} - -} diff --git a/lib/System/Unix/Path.inc b/lib/System/Unix/Path.inc deleted file mode 100644 index 47e4d1a..0000000 --- a/lib/System/Unix/Path.inc +++ /dev/null @@ -1,923 +0,0 @@ -//===- llvm/System/Unix/Path.cpp - Unix Path Implementation -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Unix specific portion of the Path class. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic UNIX code that -//=== is guaranteed to work on *all* UNIX variants. -//===----------------------------------------------------------------------===// - -#include "Unix.h" -#if HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#if HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#if HAVE_UTIME_H -#include <utime.h> -#endif -#if HAVE_TIME_H -#include <time.h> -#endif -#if HAVE_DIRENT_H -# include <dirent.h> -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# if HAVE_SYS_NDIR_H -# include <sys/ndir.h> -# endif -# if HAVE_SYS_DIR_H -# include <sys/dir.h> -# endif -# if HAVE_NDIR_H -# include <ndir.h> -# endif -#endif - -#if HAVE_DLFCN_H -#include <dlfcn.h> -#endif - -#ifdef __APPLE__ -#include <mach-o/dyld.h> -#endif - -// Put in a hack for Cygwin which falsely reports that the mkdtemp function -// is available when it is not. -#ifdef __CYGWIN__ -# undef HAVE_MKDTEMP -#endif - -namespace { -inline bool lastIsSlash(const std::string& path) { - return !path.empty() && path[path.length() - 1] == '/'; -} - -} - -namespace llvm { -using namespace sys; - -const char sys::PathSeparator = ':'; - -Path::Path(StringRef p) - : path(p) {} - -Path::Path(const char *StrStart, unsigned StrLen) - : path(StrStart, StrLen) {} - -Path& -Path::operator=(StringRef that) { - path.assign(that.data(), that.size()); - return *this; -} - -bool -Path::isValid() const { - // Check some obvious things - if (path.empty()) - return false; - return path.length() < MAXPATHLEN; -} - -bool -Path::isAbsolute(const char *NameStart, unsigned NameLen) { - assert(NameStart); - if (NameLen == 0) - return false; - return NameStart[0] == '/'; -} - -bool -Path::isAbsolute() const { - if (path.empty()) - return false; - return path[0] == '/'; -} - -void Path::makeAbsolute() { - if (isAbsolute()) - return; - - Path CWD = Path::GetCurrentDirectory(); - assert(CWD.isAbsolute() && "GetCurrentDirectory returned relative path!"); - - CWD.appendComponent(path); - - path = CWD.str(); -} - -Path -Path::GetRootDirectory() { - Path result; - result.set("/"); - return result; -} - -Path -Path::GetTemporaryDirectory(std::string *ErrMsg) { -#if defined(HAVE_MKDTEMP) - // The best way is with mkdtemp but that's not available on many systems, - // Linux and FreeBSD have it. Others probably won't. - char pathname[MAXPATHLEN]; - strcpy(pathname,"/tmp/llvm_XXXXXX"); - if (0 == mkdtemp(pathname)) { - MakeErrMsg(ErrMsg, - std::string(pathname) + ": can't create temporary directory"); - return Path(); - } - Path result; - result.set(pathname); - assert(result.isValid() && "mkdtemp didn't create a valid pathname!"); - return result; -#elif defined(HAVE_MKSTEMP) - // If no mkdtemp is available, mkstemp can be used to create a temporary file - // which is then removed and created as a directory. We prefer this over - // mktemp because of mktemp's inherent security and threading risks. We still - // have a slight race condition from the time the temporary file is created to - // the time it is re-created as a directoy. - char pathname[MAXPATHLEN]; - strcpy(pathname, "/tmp/llvm_XXXXXX"); - int fd = 0; - if (-1 == (fd = mkstemp(pathname))) { - MakeErrMsg(ErrMsg, - std::string(pathname) + ": can't create temporary directory"); - return Path(); - } - ::close(fd); - ::unlink(pathname); // start race condition, ignore errors - if (-1 == ::mkdir(pathname, S_IRWXU)) { // end race condition - MakeErrMsg(ErrMsg, - std::string(pathname) + ": can't create temporary directory"); - return Path(); - } - Path result; - result.set(pathname); - assert(result.isValid() && "mkstemp didn't create a valid pathname!"); - return result; -#elif defined(HAVE_MKTEMP) - // If a system doesn't have mkdtemp(3) or mkstemp(3) but it does have - // mktemp(3) then we'll assume that system (e.g. AIX) has a reasonable - // implementation of mktemp(3) and doesn't follow BSD 4.3's lead of replacing - // the XXXXXX with the pid of the process and a letter. That leads to only - // twenty six temporary files that can be generated. - char pathname[MAXPATHLEN]; - strcpy(pathname, "/tmp/llvm_XXXXXX"); - char *TmpName = ::mktemp(pathname); - if (TmpName == 0) { - MakeErrMsg(ErrMsg, - std::string(TmpName) + ": can't create unique directory name"); - return Path(); - } - if (-1 == ::mkdir(TmpName, S_IRWXU)) { - MakeErrMsg(ErrMsg, - std::string(TmpName) + ": can't create temporary directory"); - return Path(); - } - Path result; - result.set(TmpName); - assert(result.isValid() && "mktemp didn't create a valid pathname!"); - return result; -#else - // This is the worst case implementation. tempnam(3) leaks memory unless its - // on an SVID2 (or later) system. On BSD 4.3 it leaks. tmpnam(3) has thread - // issues. The mktemp(3) function doesn't have enough variability in the - // temporary name generated. So, we provide our own implementation that - // increments an integer from a random number seeded by the current time. This - // should be sufficiently unique that we don't have many collisions between - // processes. Generally LLVM processes don't run very long and don't use very - // many temporary files so this shouldn't be a big issue for LLVM. - static time_t num = ::time(0); - char pathname[MAXPATHLEN]; - do { - num++; - sprintf(pathname, "/tmp/llvm_%010u", unsigned(num)); - } while ( 0 == access(pathname, F_OK ) ); - if (-1 == ::mkdir(pathname, S_IRWXU)) { - MakeErrMsg(ErrMsg, - std::string(pathname) + ": can't create temporary directory"); - return Path(); - } - Path result; - result.set(pathname); - assert(result.isValid() && "mkstemp didn't create a valid pathname!"); - return result; -#endif -} - -void -Path::GetSystemLibraryPaths(std::vector<sys::Path>& Paths) { -#ifdef LTDL_SHLIBPATH_VAR - char* env_var = getenv(LTDL_SHLIBPATH_VAR); - if (env_var != 0) { - getPathList(env_var,Paths); - } -#endif - // FIXME: Should this look at LD_LIBRARY_PATH too? - Paths.push_back(sys::Path("/usr/local/lib/")); - Paths.push_back(sys::Path("/usr/X11R6/lib/")); - Paths.push_back(sys::Path("/usr/lib/")); - Paths.push_back(sys::Path("/lib/")); -} - -void -Path::GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths) { - char * env_var = getenv("LLVM_LIB_SEARCH_PATH"); - if (env_var != 0) { - getPathList(env_var,Paths); - } -#ifdef LLVM_LIBDIR - { - Path tmpPath; - if (tmpPath.set(LLVM_LIBDIR)) - if (tmpPath.canRead()) - Paths.push_back(tmpPath); - } -#endif - GetSystemLibraryPaths(Paths); -} - -Path -Path::GetLLVMDefaultConfigDir() { - return Path("/etc/llvm/"); -} - -Path -Path::GetUserHomeDirectory() { - const char* home = getenv("HOME"); - if (home) { - Path result; - if (result.set(home)) - return result; - } - return GetRootDirectory(); -} - -Path -Path::GetCurrentDirectory() { - char pathname[MAXPATHLEN]; - if (!getcwd(pathname,MAXPATHLEN)) { - assert (false && "Could not query current working directory."); - return Path(); - } - - return Path(pathname); -} - -#if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__minix) -static int -test_dir(char buf[PATH_MAX], char ret[PATH_MAX], - const char *dir, const char *bin) -{ - struct stat sb; - - snprintf(buf, PATH_MAX, "%s/%s", dir, bin); - if (realpath(buf, ret) == NULL) - return (1); - if (stat(buf, &sb) != 0) - return (1); - - return (0); -} - -static char * -getprogpath(char ret[PATH_MAX], const char *bin) -{ - char *pv, *s, *t, buf[PATH_MAX]; - - /* First approach: absolute path. */ - if (bin[0] == '/') { - if (test_dir(buf, ret, "/", bin) == 0) - return (ret); - return (NULL); - } - - /* Second approach: relative path. */ - if (strchr(bin, '/') != NULL) { - if (getcwd(buf, PATH_MAX) == NULL) - return (NULL); - if (test_dir(buf, ret, buf, bin) == 0) - return (ret); - return (NULL); - } - - /* Third approach: $PATH */ - if ((pv = getenv("PATH")) == NULL) - return (NULL); - s = pv = strdup(pv); - if (pv == NULL) - return (NULL); - while ((t = strsep(&s, ":")) != NULL) { - if (test_dir(buf, ret, t, bin) == 0) { - free(pv); - return (ret); - } - } - free(pv); - return (NULL); -} -#endif // __FreeBSD__ || __NetBSD__ - -/// GetMainExecutable - Return the path to the main executable, given the -/// value of argv[0] from program startup. -Path Path::GetMainExecutable(const char *argv0, void *MainAddr) { -#if defined(__APPLE__) - // On OS X the executable path is saved to the stack by dyld. Reading it - // from there is much faster than calling dladdr, especially for large - // binaries with symbols. - char exe_path[MAXPATHLEN]; - uint32_t size = sizeof(exe_path); - if (_NSGetExecutablePath(exe_path, &size) == 0) { - char link_path[MAXPATHLEN]; - if (realpath(exe_path, link_path)) - return Path(std::string(link_path)); - } -#elif defined(__FreeBSD__) || defined (__NetBSD__) || defined(__minix) - char exe_path[PATH_MAX]; - - if (getprogpath(exe_path, argv0) != NULL) - return Path(std::string(exe_path)); -#elif defined(__linux__) || defined(__CYGWIN__) - char exe_path[MAXPATHLEN]; - ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path)); - if (len >= 0) - return Path(std::string(exe_path, len)); -#elif defined(HAVE_DLFCN_H) - // Use dladdr to get executable path if available. - Dl_info DLInfo; - int err = dladdr(MainAddr, &DLInfo); - if (err == 0) - return Path(); - - // If the filename is a symlink, we need to resolve and return the location of - // the actual executable. - char link_path[MAXPATHLEN]; - if (realpath(DLInfo.dli_fname, link_path)) - return Path(std::string(link_path)); -#endif - return Path(); -} - - -StringRef Path::getDirname() const { - return getDirnameCharSep(path, "/"); -} - -StringRef -Path::getBasename() const { - // Find the last slash - std::string::size_type slash = path.rfind('/'); - if (slash == std::string::npos) - slash = 0; - else - slash++; - - std::string::size_type dot = path.rfind('.'); - if (dot == std::string::npos || dot < slash) - return StringRef(path).substr(slash); - else - return StringRef(path).substr(slash, dot - slash); -} - -StringRef -Path::getSuffix() const { - // Find the last slash - std::string::size_type slash = path.rfind('/'); - if (slash == std::string::npos) - slash = 0; - else - slash++; - - std::string::size_type dot = path.rfind('.'); - if (dot == std::string::npos || dot < slash) - return StringRef(); - else - return StringRef(path).substr(dot + 1); -} - -bool Path::getMagicNumber(std::string &Magic, unsigned len) const { - assert(len < 1024 && "Request for magic string too long"); - char Buf[1025]; - int fd = ::open(path.c_str(), O_RDONLY); - if (fd < 0) - return false; - ssize_t bytes_read = ::read(fd, Buf, len); - ::close(fd); - if (ssize_t(len) != bytes_read) - return false; - Magic.assign(Buf, len); - return true; -} - -bool -Path::exists() const { - return 0 == access(path.c_str(), F_OK ); -} - -bool -Path::isDirectory() const { - struct stat buf; - if (0 != stat(path.c_str(), &buf)) - return false; - return buf.st_mode & S_IFDIR ? true : false; -} - -bool -Path::canRead() const { - return 0 == access(path.c_str(), R_OK); -} - -bool -Path::canWrite() const { - return 0 == access(path.c_str(), W_OK); -} - -bool -Path::isRegularFile() const { - // Get the status so we can determine if it's a file or directory - struct stat buf; - - if (0 != stat(path.c_str(), &buf)) - return false; - - if (S_ISREG(buf.st_mode)) - return true; - - return false; -} - -bool -Path::canExecute() const { - if (0 != access(path.c_str(), R_OK | X_OK )) - return false; - struct stat buf; - if (0 != stat(path.c_str(), &buf)) - return false; - if (!S_ISREG(buf.st_mode)) - return false; - return true; -} - -StringRef -Path::getLast() const { - // Find the last slash - size_t pos = path.rfind('/'); - - // Handle the corner cases - if (pos == std::string::npos) - return path; - - // If the last character is a slash - if (pos == path.length()-1) { - // Find the second to last slash - size_t pos2 = path.rfind('/', pos-1); - if (pos2 == std::string::npos) - return StringRef(path).substr(0,pos); - else - return StringRef(path).substr(pos2+1,pos-pos2-1); - } - // Return everything after the last slash - return StringRef(path).substr(pos+1); -} - -const FileStatus * -PathWithStatus::getFileStatus(bool update, std::string *ErrStr) const { - if (!fsIsValid || update) { - struct stat buf; - if (0 != stat(path.c_str(), &buf)) { - MakeErrMsg(ErrStr, path + ": can't get status of file"); - return 0; - } - status.fileSize = buf.st_size; - status.modTime.fromEpochTime(buf.st_mtime); - status.mode = buf.st_mode; - status.user = buf.st_uid; - status.group = buf.st_gid; - status.uniqueID = uint64_t(buf.st_ino); - status.isDir = S_ISDIR(buf.st_mode); - status.isFile = S_ISREG(buf.st_mode); - fsIsValid = true; - } - return &status; -} - -static bool AddPermissionBits(const Path &File, int bits) { - // Get the umask value from the operating system. We want to use it - // when changing the file's permissions. Since calling umask() sets - // the umask and returns its old value, we must call it a second - // time to reset it to the user's preference. - int mask = umask(0777); // The arg. to umask is arbitrary. - umask(mask); // Restore the umask. - - // Get the file's current mode. - struct stat buf; - if (0 != stat(File.c_str(), &buf)) - return false; - // Change the file to have whichever permissions bits from 'bits' - // that the umask would not disable. - if ((chmod(File.c_str(), (buf.st_mode | (bits & ~mask)))) == -1) - return false; - return true; -} - -bool Path::makeReadableOnDisk(std::string* ErrMsg) { - if (!AddPermissionBits(*this, 0444)) - return MakeErrMsg(ErrMsg, path + ": can't make file readable"); - return false; -} - -bool Path::makeWriteableOnDisk(std::string* ErrMsg) { - if (!AddPermissionBits(*this, 0222)) - return MakeErrMsg(ErrMsg, path + ": can't make file writable"); - return false; -} - -bool Path::makeExecutableOnDisk(std::string* ErrMsg) { - if (!AddPermissionBits(*this, 0111)) - return MakeErrMsg(ErrMsg, path + ": can't make file executable"); - return false; -} - -bool -Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const { - DIR* direntries = ::opendir(path.c_str()); - if (direntries == 0) - return MakeErrMsg(ErrMsg, path + ": can't open directory"); - - std::string dirPath = path; - if (!lastIsSlash(dirPath)) - dirPath += '/'; - - result.clear(); - struct dirent* de = ::readdir(direntries); - for ( ; de != 0; de = ::readdir(direntries)) { - if (de->d_name[0] != '.') { - Path aPath(dirPath + (const char*)de->d_name); - struct stat st; - if (0 != lstat(aPath.path.c_str(), &st)) { - if (S_ISLNK(st.st_mode)) - continue; // dangling symlink -- ignore - return MakeErrMsg(ErrMsg, - aPath.path + ": can't determine file object type"); - } - result.insert(aPath); - } - } - - closedir(direntries); - return false; -} - -bool -Path::set(StringRef a_path) { - if (a_path.empty()) - return false; - std::string save(path); - path = a_path; - if (!isValid()) { - path = save; - return false; - } - return true; -} - -bool -Path::appendComponent(StringRef name) { - if (name.empty()) - return false; - std::string save(path); - if (!lastIsSlash(path)) - path += '/'; - path += name; - if (!isValid()) { - path = save; - return false; - } - return true; -} - -bool -Path::eraseComponent() { - size_t slashpos = path.rfind('/',path.size()); - if (slashpos == 0 || slashpos == std::string::npos) { - path.erase(); - return true; - } - if (slashpos == path.size() - 1) - slashpos = path.rfind('/',slashpos-1); - if (slashpos == std::string::npos) { - path.erase(); - return true; - } - path.erase(slashpos); - return true; -} - -bool -Path::appendSuffix(StringRef suffix) { - std::string save(path); - path.append("."); - path.append(suffix); - if (!isValid()) { - path = save; - return false; - } - return true; -} - -bool -Path::eraseSuffix() { - std::string save = path; - size_t dotpos = path.rfind('.',path.size()); - size_t slashpos = path.rfind('/',path.size()); - if (dotpos != std::string::npos) { - if (slashpos == std::string::npos || dotpos > slashpos+1) { - path.erase(dotpos, path.size()-dotpos); - return true; - } - } - if (!isValid()) - path = save; - return false; -} - -static bool createDirectoryHelper(char* beg, char* end, bool create_parents) { - - if (access(beg, R_OK | W_OK) == 0) - return false; - - if (create_parents) { - - char* c = end; - - for (; c != beg; --c) - if (*c == '/') { - - // Recurse to handling the parent directory. - *c = '\0'; - bool x = createDirectoryHelper(beg, c, create_parents); - *c = '/'; - - // Return if we encountered an error. - if (x) - return true; - - break; - } - } - - return mkdir(beg, S_IRWXU | S_IRWXG) != 0; -} - -bool -Path::createDirectoryOnDisk( bool create_parents, std::string* ErrMsg ) { - // Get a writeable copy of the path name - char pathname[MAXPATHLEN]; - path.copy(pathname,MAXPATHLEN); - - // Null-terminate the last component - size_t lastchar = path.length() - 1 ; - - if (pathname[lastchar] != '/') - ++lastchar; - - pathname[lastchar] = 0; - - if (createDirectoryHelper(pathname, pathname+lastchar, create_parents)) - return MakeErrMsg(ErrMsg, - std::string(pathname) + ": can't create directory"); - - return false; -} - -bool -Path::createFileOnDisk(std::string* ErrMsg) { - // Create the file - int fd = ::creat(path.c_str(), S_IRUSR | S_IWUSR); - if (fd < 0) - return MakeErrMsg(ErrMsg, path + ": can't create file"); - ::close(fd); - return false; -} - -bool -Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) { - // Make this into a unique file name - if (makeUnique( reuse_current, ErrMsg )) - return true; - - // create the file - int fd = ::open(path.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0666); - if (fd < 0) - return MakeErrMsg(ErrMsg, path + ": can't create temporary file"); - ::close(fd); - return false; -} - -bool -Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const { - // 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"); - return true; - } - - // Note: this check catches strange situations. In all cases, LLVM should - // only be involved in the creation and deletion of regular files. This - // check ensures that what we're trying to erase is a regular file. It - // effectively prevents LLVM from erasing things like /dev/null, any block - // special file, or other things that aren't "regular" files. - if (S_ISREG(buf.st_mode)) { - if (unlink(path.c_str()) != 0) - return MakeErrMsg(ErrStr, path + ": can't destroy file"); - return false; - } - - if (!S_ISDIR(buf.st_mode)) { - if (ErrStr) *ErrStr = "not a file or directory"; - return true; - } - - if (remove_contents) { - // Recursively descend the directory to remove its contents. - std::string cmd = "/bin/rm -rf " + path; - if (system(cmd.c_str()) != 0) { - MakeErrMsg(ErrStr, path + ": failed to recursively remove directory."); - return true; - } - return false; - } - - // Otherwise, try to just remove the one directory. - char pathname[MAXPATHLEN]; - path.copy(pathname, MAXPATHLEN); - size_t lastchar = path.length() - 1; - if (pathname[lastchar] == '/') - pathname[lastchar] = 0; - else - pathname[lastchar+1] = 0; - - if (rmdir(pathname) != 0) - return MakeErrMsg(ErrStr, - std::string(pathname) + ": can't erase directory"); - return false; -} - -bool -Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) { - if (0 != ::rename(path.c_str(), newName.c_str())) - return MakeErrMsg(ErrMsg, std::string("can't rename '") + path + "' as '" + - newName.str() + "'"); - return false; -} - -bool -Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrStr) const { - struct utimbuf utb; - utb.actime = si.modTime.toPosixTime(); - utb.modtime = utb.actime; - if (0 != ::utime(path.c_str(),&utb)) - return MakeErrMsg(ErrStr, path + ": can't set file modification time"); - if (0 != ::chmod(path.c_str(),si.mode)) - return MakeErrMsg(ErrStr, path + ": can't set mode"); - return false; -} - -bool -sys::CopyFile(const sys::Path &Dest, const sys::Path &Src, std::string* ErrMsg){ - int inFile = -1; - int outFile = -1; - inFile = ::open(Src.c_str(), O_RDONLY); - if (inFile == -1) - return MakeErrMsg(ErrMsg, Src.str() + - ": can't open source file to copy"); - - outFile = ::open(Dest.c_str(), O_WRONLY|O_CREAT, 0666); - if (outFile == -1) { - ::close(inFile); - return MakeErrMsg(ErrMsg, Dest.str() + - ": can't create destination file for copy"); - } - - char Buffer[16*1024]; - while (ssize_t Amt = ::read(inFile, Buffer, 16*1024)) { - if (Amt == -1) { - if (errno != EINTR && errno != EAGAIN) { - ::close(inFile); - ::close(outFile); - return MakeErrMsg(ErrMsg, Src.str()+": can't read source file"); - } - } else { - char *BufPtr = Buffer; - while (Amt) { - ssize_t AmtWritten = ::write(outFile, BufPtr, Amt); - if (AmtWritten == -1) { - if (errno != EINTR && errno != EAGAIN) { - ::close(inFile); - ::close(outFile); - return MakeErrMsg(ErrMsg, Dest.str() + - ": can't write destination file"); - } - } else { - Amt -= AmtWritten; - BufPtr += AmtWritten; - } - } - } - } - ::close(inFile); - ::close(outFile); - return false; -} - -bool -Path::makeUnique(bool reuse_current, std::string* ErrMsg) { - if (reuse_current && !exists()) - return false; // File doesn't exist already, just use it! - - // Append an XXXXXX pattern to the end of the file for use with mkstemp, - // mktemp or our own implementation. - // 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()) - strcpy(FNBuffer+path.size(), "/XXXXXX"); - else - strcpy(FNBuffer+path.size(), "-XXXXXX"); - -#if defined(HAVE_MKSTEMP) - int TempFD; - 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 - // will overwrite/delete the file before we can open it again. - close(TempFD); - - // Save the name - path = FNBuffer; -#elif defined(HAVE_MKTEMP) - // If we don't have mkstemp, use the old and obsolete mktemp function. - if (mktemp(FNBuffer) == 0) - return MakeErrMsg(ErrMsg, path + ": can't make unique filename"); - - // Save the name - path = FNBuffer; -#else - // Okay, looks like we have to do it all by our lonesome. - static unsigned FCounter = 0; - // Try to initialize with unique value. - if (FCounter == 0) FCounter = ((unsigned)getpid() & 0xFFFF) << 8; - char* pos = strstr(FNBuffer, "XXXXXX"); - do { - if (++FCounter > 0xFFFFFF) { - return MakeErrMsg(ErrMsg, - path + ": can't make unique filename: too many files"); - } - sprintf(pos, "%06X", FCounter); - path = FNBuffer; - } while (exists()); - // POSSIBLE SECURITY BUG: An attacker can easily guess the name and exploit - // LLVM. -#endif - return false; -} - -const char *Path::MapInFilePages(int FD, uint64_t FileSize) { - int Flags = MAP_PRIVATE; -#ifdef MAP_FILE - Flags |= MAP_FILE; -#endif - void *BasePtr = ::mmap(0, FileSize, PROT_READ, Flags, FD, 0); - if (BasePtr == MAP_FAILED) - return 0; - return (const char*)BasePtr; -} - -void Path::UnMapFilePages(const char *BasePtr, uint64_t FileSize) { - ::munmap((void*)BasePtr, FileSize); -} - -} // end llvm namespace diff --git a/lib/System/Unix/Process.inc b/lib/System/Unix/Process.inc deleted file mode 100644 index cf6a47a..0000000 --- a/lib/System/Unix/Process.inc +++ /dev/null @@ -1,295 +0,0 @@ -//===- Unix/Process.cpp - Unix Process Implementation --------- -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides the generic Unix implementation of the Process class. -// -//===----------------------------------------------------------------------===// - -#include "Unix.h" -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#ifdef HAVE_SYS_RESOURCE_H -#include <sys/resource.h> -#endif -// DragonFly BSD has deprecated <malloc.h> for <stdlib.h> instead, -// Unix.h includes this for us already. -#if defined(HAVE_MALLOC_H) && !defined(__DragonFly__) -#include <malloc.h> -#endif -#ifdef HAVE_MALLOC_MALLOC_H -#include <malloc/malloc.h> -#endif -#ifdef HAVE_SYS_IOCTL_H -# include <sys/ioctl.h> -#endif -#ifdef HAVE_TERMIOS_H -# include <termios.h> -#endif - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic UNIX code that -//=== is guaranteed to work on *all* UNIX variants. -//===----------------------------------------------------------------------===// - -using namespace llvm; -using namespace sys; - -unsigned -Process::GetPageSize() -{ -#if defined(__CYGWIN__) - // On Cygwin, getpagesize() returns 64k but the page size for the purposes of - // memory protection and mmap() is 4k. - // See http://www.cygwin.com/ml/cygwin/2009-01/threads.html#00492 - const int page_size = 0x1000; -#elif defined(HAVE_GETPAGESIZE) - const int page_size = ::getpagesize(); -#elif defined(HAVE_SYSCONF) - long page_size = ::sysconf(_SC_PAGE_SIZE); -#else -#warning Cannot get the page size on this machine -#endif - return static_cast<unsigned>(page_size); -} - -size_t Process::GetMallocUsage() { -#if defined(HAVE_MALLINFO) - struct mallinfo mi; - mi = ::mallinfo(); - return mi.uordblks; -#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H) - malloc_statistics_t Stats; - malloc_zone_statistics(malloc_default_zone(), &Stats); - return Stats.size_in_use; // darwin -#elif defined(HAVE_SBRK) - // Note this is only an approximation and more closely resembles - // the value returned by mallinfo in the arena field. - static char *StartOfMemory = reinterpret_cast<char*>(::sbrk(0)); - char *EndOfMemory = (char*)sbrk(0); - if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1)) - return EndOfMemory - StartOfMemory; - else - return 0; -#else -#warning Cannot get malloc info on this platform - return 0; -#endif -} - -size_t -Process::GetTotalMemoryUsage() -{ -#if defined(HAVE_MALLINFO) - struct mallinfo mi = ::mallinfo(); - return mi.uordblks + mi.hblkhd; -#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H) - malloc_statistics_t Stats; - malloc_zone_statistics(malloc_default_zone(), &Stats); - return Stats.size_allocated; // darwin -#elif defined(HAVE_GETRUSAGE) && !defined(__HAIKU__) - struct rusage usage; - ::getrusage(RUSAGE_SELF, &usage); - return usage.ru_maxrss; -#else -#warning Cannot get total memory size on this platform - return 0; -#endif -} - -void -Process::GetTimeUsage(TimeValue& elapsed, TimeValue& user_time, - TimeValue& sys_time) -{ - elapsed = TimeValue::now(); -#if defined(HAVE_GETRUSAGE) - struct rusage usage; - ::getrusage(RUSAGE_SELF, &usage); - user_time = TimeValue( - static_cast<TimeValue::SecondsType>( usage.ru_utime.tv_sec ), - static_cast<TimeValue::NanoSecondsType>( usage.ru_utime.tv_usec * - TimeValue::NANOSECONDS_PER_MICROSECOND ) ); - sys_time = TimeValue( - static_cast<TimeValue::SecondsType>( usage.ru_stime.tv_sec ), - static_cast<TimeValue::NanoSecondsType>( usage.ru_stime.tv_usec * - TimeValue::NANOSECONDS_PER_MICROSECOND ) ); -#else -#warning Cannot get usage times on this platform - user_time.seconds(0); - user_time.microseconds(0); - sys_time.seconds(0); - sys_time.microseconds(0); -#endif -} - -int Process::GetCurrentUserId() { - return getuid(); -} - -int Process::GetCurrentGroupId() { - return getgid(); -} - -#ifdef HAVE_MACH_MACH_H -#include <mach/mach.h> -#endif - -// Some LLVM programs such as bugpoint produce core files as a normal part of -// their operation. To prevent the disk from filling up, this function -// does what's necessary to prevent their generation. -void Process::PreventCoreFiles() { -#if HAVE_SETRLIMIT - struct rlimit rlim; - rlim.rlim_cur = rlim.rlim_max = 0; - setrlimit(RLIMIT_CORE, &rlim); -#endif - -#ifdef HAVE_MACH_MACH_H - // Disable crash reporting on Mac OS X 10.0-10.4 - - // get information about the original set of exception ports for the task - mach_msg_type_number_t Count = 0; - exception_mask_t OriginalMasks[EXC_TYPES_COUNT]; - exception_port_t OriginalPorts[EXC_TYPES_COUNT]; - exception_behavior_t OriginalBehaviors[EXC_TYPES_COUNT]; - thread_state_flavor_t OriginalFlavors[EXC_TYPES_COUNT]; - kern_return_t err = - task_get_exception_ports(mach_task_self(), EXC_MASK_ALL, OriginalMasks, - &Count, OriginalPorts, OriginalBehaviors, - OriginalFlavors); - if (err == KERN_SUCCESS) { - // replace each with MACH_PORT_NULL. - for (unsigned i = 0; i != Count; ++i) - task_set_exception_ports(mach_task_self(), OriginalMasks[i], - MACH_PORT_NULL, OriginalBehaviors[i], - OriginalFlavors[i]); - } - - // Disable crash reporting on Mac OS X 10.5 - signal(SIGABRT, _exit); - signal(SIGILL, _exit); - signal(SIGFPE, _exit); - signal(SIGSEGV, _exit); - signal(SIGBUS, _exit); -#endif -} - -bool Process::StandardInIsUserInput() { - return FileDescriptorIsDisplayed(STDIN_FILENO); -} - -bool Process::StandardOutIsDisplayed() { - return FileDescriptorIsDisplayed(STDOUT_FILENO); -} - -bool Process::StandardErrIsDisplayed() { - return FileDescriptorIsDisplayed(STDERR_FILENO); -} - -bool Process::FileDescriptorIsDisplayed(int fd) { -#if HAVE_ISATTY - return isatty(fd); -#else - // If we don't have isatty, just return false. - return false; -#endif -} - -static unsigned getColumns(int FileID) { - // If COLUMNS is defined in the environment, wrap to that many columns. - if (const char *ColumnsStr = std::getenv("COLUMNS")) { - int Columns = std::atoi(ColumnsStr); - if (Columns > 0) - return Columns; - } - - unsigned Columns = 0; - -#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_TERMIOS_H) - // Try to determine the width of the terminal. - struct winsize ws; - if (ioctl(FileID, TIOCGWINSZ, &ws) == 0) - Columns = ws.ws_col; -#endif - - return Columns; -} - -unsigned Process::StandardOutColumns() { - if (!StandardOutIsDisplayed()) - return 0; - - return getColumns(1); -} - -unsigned Process::StandardErrColumns() { - if (!StandardErrIsDisplayed()) - return 0; - - return getColumns(2); -} - -static bool terminalHasColors() { - if (const char *term = std::getenv("TERM")) { - // Most modern terminals support ANSI escape sequences for colors. - // We could check terminfo, or have a list of known terms that support - // colors, but that would be overkill. - // The user can always ask for no colors by setting TERM to dumb, or - // using a commandline flag. - return strcmp(term, "dumb") != 0; - } - return false; -} - -bool Process::StandardOutHasColors() { - if (!StandardOutIsDisplayed()) - return false; - return terminalHasColors(); -} - -bool Process::StandardErrHasColors() { - if (!StandardErrIsDisplayed()) - return false; - return terminalHasColors(); -} - -bool Process::ColorNeedsFlush() { - // No, we use ANSI escape sequences. - return false; -} - -#define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m" - -#define ALLCOLORS(FGBG,BOLD) {\ - COLOR(FGBG, "0", BOLD),\ - COLOR(FGBG, "1", BOLD),\ - COLOR(FGBG, "2", BOLD),\ - COLOR(FGBG, "3", BOLD),\ - COLOR(FGBG, "4", BOLD),\ - COLOR(FGBG, "5", BOLD),\ - COLOR(FGBG, "6", BOLD),\ - COLOR(FGBG, "7", BOLD)\ - } - -static const char colorcodes[2][2][8][10] = { - { ALLCOLORS("3",""), ALLCOLORS("3","1;") }, - { ALLCOLORS("4",""), ALLCOLORS("4","1;") } -}; - -const char *Process::OutputColor(char code, bool bold, bool bg) { - return colorcodes[bg?1:0][bold?1:0][code&7]; -} - -const char *Process::OutputBold(bool bg) { - return "\033[1m"; -} - -const char *Process::ResetColor() { - return "\033[0m"; -} diff --git a/lib/System/Unix/Program.inc b/lib/System/Unix/Program.inc deleted file mode 100644 index 0209f5a..0000000 --- a/lib/System/Unix/Program.inc +++ /dev/null @@ -1,402 +0,0 @@ -//===- llvm/System/Unix/Program.cpp -----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Unix specific portion of the Program class. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic UNIX code that -//=== is guaranteed to work on *all* UNIX variants. -//===----------------------------------------------------------------------===// - -#include <llvm/Config/config.h> -#include "Unix.h" -#if HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#if HAVE_SYS_RESOURCE_H -#include <sys/resource.h> -#endif -#if HAVE_SIGNAL_H -#include <signal.h> -#endif -#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; - -Program::Program() : Data_(0) {} - -Program::~Program() {} - -unsigned Program::GetPid() const { - uint64_t pid = reinterpret_cast<uint64_t>(Data_); - return static_cast<unsigned>(pid); -} - -// This function just uses the PATH environment variable to find the program. -Path -Program::FindProgramByName(const std::string& progName) { - - // Check some degenerate cases - if (progName.length() == 0) // no program - return Path(); - Path temp; - if (!temp.set(progName)) // invalid name - return Path(); - // Use the given path verbatim if it contains any slashes; this matches - // the behavior of sh(1) and friends. - if (progName.find('/') != std::string::npos) - return temp; - - // At this point, the file name does not contain slashes. Search for it - // through the directories specified in the PATH environment variable. - - // Get the path. If its empty, we can't do anything to find it. - const char *PathStr = getenv("PATH"); - if (PathStr == 0) - return Path(); - - // Now we have a colon separated list of directories to search; try them. - size_t PathLen = strlen(PathStr); - while (PathLen) { - // Find the first colon... - const char *Colon = std::find(PathStr, PathStr+PathLen, ':'); - - // Check to see if this first directory contains the executable... - Path FilePath; - if (FilePath.set(std::string(PathStr,Colon))) { - FilePath.appendComponent(progName); - if (FilePath.canExecute()) - return FilePath; // Found the executable! - } - - // Nope it wasn't in this directory, check the next path in the list! - PathLen -= Colon-PathStr; - PathStr = Colon; - - // Advance past duplicate colons - while (*PathStr == ':') { - PathStr++; - PathLen--; - } - } - return Path(); -} - -static bool RedirectIO(const Path *Path, int FD, std::string* ErrMsg) { - 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(); - - // Open the file - int InFD = open(File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666); - if (InFD == -1) { - MakeErrMsg(ErrMsg, "Cannot open file '" + std::string(File) + "' for " - + (FD == 0 ? "input" : "output")); - return true; - } - - // Install it as the requested 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) { -} - -static void SetMemoryLimits (unsigned size) -{ -#if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT - struct rlimit r; - __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576; - - // Heap size - getrlimit (RLIMIT_DATA, &r); - r.rlim_cur = limit; - setrlimit (RLIMIT_DATA, &r); -#ifdef RLIMIT_RSS - // Resident set size. - getrlimit (RLIMIT_RSS, &r); - r.rlim_cur = limit; - setrlimit (RLIMIT_RSS, &r); -#endif -#ifdef RLIMIT_AS // e.g. NetBSD doesn't have it. - // Virtual memory. - getrlimit (RLIMIT_AS, &r); - r.rlim_cur = limit; - setrlimit (RLIMIT_AS, &r); -#endif -#endif -} - -bool -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"; - return false; - } - - // Create a child process. - int child = fork(); - switch (child) { - // An error occured: Return to the caller. - case -1: - MakeErrMsg(ErrMsg, "Couldn't fork"); - return false; - - // Child process: Execute the program. - case 0: { - // Redirect file descriptors... - if (redirects) { - // Redirect stdin - if (RedirectIO(redirects[0], 0, ErrMsg)) { return false; } - // Redirect stdout - if (RedirectIO(redirects[1], 1, ErrMsg)) { return false; } - if (redirects[1] && redirects[2] && - *(redirects[1]) == *(redirects[2])) { - // If stdout and stderr should go to the same place, redirect stderr - // to the FD already open for stdout. - if (-1 == dup2(1,2)) { - MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout"); - return false; - } - } else { - // Just redirect stderr - if (RedirectIO(redirects[2], 2, ErrMsg)) { return false; } - } - } - - // Set memory limits - if (memoryLimit!=0) { - SetMemoryLimits(memoryLimit); - } - - // Execute! - if (envp != 0) - execve(path.c_str(), - const_cast<char **>(args), - const_cast<char **>(envp)); - else - 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 - // object destructors cloned from the parent process aren't - // redundantly run, and so that any data buffered in stdio buffers - // cloned from the parent aren't redundantly written out. - _exit(errno == ENOENT ? 127 : 126); - } - - // Parent process: Break out of the switch to do our processing. - default: - break; - } - - Data_ = reinterpret_cast<void*>(child); - - return true; -} - -int -Program::Wait(unsigned secondsToWait, - std::string* ErrMsg) -{ -#ifdef HAVE_SYS_WAIT_H - struct sigaction Act, Old; - - if (Data_ == 0) { - MakeErrMsg(ErrMsg, "Process not started!"); - return -1; - } - - // Install a timeout handler. The handler itself does nothing, but the simple - // fact of having a handler at all causes the wait below to return with EINTR, - // unlike if we used SIG_IGN. - if (secondsToWait) { - memset(&Act, 0, sizeof(Act)); - Act.sa_handler = TimeOutHandler; - sigemptyset(&Act.sa_mask); - sigaction(SIGALRM, &Act, &Old); - alarm(secondsToWait); - } - - // Parent process: Wait for the child process to terminate. - int status; - uint64_t pid = reinterpret_cast<uint64_t>(Data_); - pid_t child = static_cast<pid_t>(pid); - while (waitpid(pid, &status, 0) != child) - if (secondsToWait && errno == EINTR) { - // Kill the child. - kill(child, SIGKILL); - - // Turn off the alarm and restore the signal handler - alarm(0); - sigaction(SIGALRM, &Old, 0); - - // Wait for child to die - if (wait(&status) != child) - MakeErrMsg(ErrMsg, "Child timed out but wouldn't die"); - else - MakeErrMsg(ErrMsg, "Child timed out", 0); - - return -1; // Timeout detected - } else if (errno != EINTR) { - MakeErrMsg(ErrMsg, "Error waiting for child process"); - return -1; - } - - // We exited normally without timeout, so turn off the timer. - if (secondsToWait) { - alarm(0); - sigaction(SIGALRM, &Old, 0); - } - - // Return the proper exit status. 0=success, >0 is programs' exit status, - // <0 means a signal was returned, -9999999 means the program dumped core. - int result = 0; - if (WIFEXITED(status)) - result = WEXITSTATUS(status); - else if (WIFSIGNALED(status)) - result = 0 - WTERMSIG(status); -#ifdef WCOREDUMP - else if (WCOREDUMP(status)) - result |= 0x01000000; -#endif - return result; -#else - return -99; -#endif - -} - -bool -Program::Kill(std::string* ErrMsg) { - if (Data_ == 0) { - MakeErrMsg(ErrMsg, "Process not started!"); - return true; - } - - uint64_t pid64 = reinterpret_cast<uint64_t>(Data_); - pid_t pid = static_cast<pid_t>(pid64); - - if (kill(pid, SIGKILL) != 0) { - MakeErrMsg(ErrMsg, "The process couldn't be killed!"); - return true; - } - - return false; -} - -bool Program::ChangeStdinToBinary(){ - // Do nothing, as Unix doesn't differentiate between text and binary. - return false; -} - -bool Program::ChangeStdoutToBinary(){ - // Do nothing, as Unix doesn't differentiate between text and binary. - return false; -} - -bool Program::ChangeStderrToBinary(){ - // Do nothing, as Unix doesn't differentiate between text and binary. - return false; -} - -} diff --git a/lib/System/Unix/README.txt b/lib/System/Unix/README.txt deleted file mode 100644 index b3bace4..0000000 --- a/lib/System/Unix/README.txt +++ /dev/null @@ -1,16 +0,0 @@ -llvm/lib/System/Unix README -=========================== - -This directory provides implementations of the lib/System classes that -are common to two or more variants of UNIX. For example, the directory -structure underneath this directory could look like this: - -Unix - only code that is truly generic to all UNIX platforms - Posix - code that is specific to Posix variants of UNIX - SUS - code that is specific to the Single Unix Specification - SysV - code that is specific to System V variants of UNIX - -As a rule, only those directories actually needing to be created should be -created. Also, further subdirectories could be created to reflect versions of -the various standards. For example, under SUS there could be v1, v2, and v3 -subdirectories to reflect the three major versions of SUS. diff --git a/lib/System/Unix/RWMutex.inc b/lib/System/Unix/RWMutex.inc deleted file mode 100644 index e83d41e..0000000 --- a/lib/System/Unix/RWMutex.inc +++ /dev/null @@ -1,43 +0,0 @@ -//= llvm/System/Unix/RWMutex.inc - Unix Reader/Writer Mutual Exclusion Lock =// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Unix specific (non-pthread) RWMutex class. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic UNIX code that -//=== is guaranteed to work on *all* UNIX variants. -//===----------------------------------------------------------------------===// - -namespace llvm { - -using namespace sys; - -RWMutexImpl::RWMutexImpl() { } - -RWMutexImpl::~RWMutexImpl() { } - -bool RWMutexImpl::reader_acquire() { - return true; -} - -bool RWMutexImpl::reader_release() { - return true; -} - -bool RWMutexImpl::writer_acquire() { - return true; -} - -bool RWMutexImpl::writer_release() { - return true; -} - -} diff --git a/lib/System/Unix/Signals.inc b/lib/System/Unix/Signals.inc deleted file mode 100644 index 7b7c43e..0000000 --- a/lib/System/Unix/Signals.inc +++ /dev/null @@ -1,299 +0,0 @@ -//===- Signals.cpp - Generic Unix Signals Implementation -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines some helpful functions for dealing with the possibility of -// Unix signals occuring while your program is running. -// -//===----------------------------------------------------------------------===// - -#include "Unix.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/System/Mutex.h" -#include <vector> -#include <algorithm> -#if HAVE_EXECINFO_H -# include <execinfo.h> // For backtrace(). -#endif -#if HAVE_SIGNAL_H -#include <signal.h> -#endif -#if HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#if HAVE_DLFCN_H && __GNUG__ -#include <dlfcn.h> -#include <cxxabi.h> -#endif -using namespace llvm; - -static RETSIGTYPE SignalHandler(int Sig); // defined below. - -static SmartMutex<true> SignalsMutex; - -/// InterruptFunction - The function to call if ctrl-c is pressed. -static void (*InterruptFunction)() = 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[] = { - SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2 -}; -static const int *const IntSigsEnd = - IntSigs + sizeof(IntSigs) / sizeof(IntSigs[0]); - -// KillSigs - Signals that are synchronous with the program that will cause it -// to die. -static const int KillSigs[] = { - SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV -#ifdef SIGSYS - , SIGSYS -#endif -#ifdef SIGXCPU - , SIGXCPU -#endif -#ifdef SIGXFSZ - , SIGXFSZ -#endif -#ifdef SIGEMT - , SIGEMT -#endif -}; -static const int *const KillSigsEnd = - KillSigs + sizeof(KillSigs) / sizeof(KillSigs[0]); - -static unsigned NumRegisteredSignals = 0; -static struct { - struct sigaction SA; - int SigNo; -} RegisteredSignalInfo[(sizeof(IntSigs)+sizeof(KillSigs))/sizeof(KillSigs[0])]; - - -static void RegisterHandler(int Signal) { - assert(NumRegisteredSignals < - sizeof(RegisteredSignalInfo)/sizeof(RegisteredSignalInfo[0]) && - "Out of space for signal handlers!"); - - struct sigaction NewHandler; - - NewHandler.sa_handler = SignalHandler; - NewHandler.sa_flags = SA_NODEFER|SA_RESETHAND; - sigemptyset(&NewHandler.sa_mask); - - // Install the new handler, save the old one in RegisteredSignalInfo. - sigaction(Signal, &NewHandler, - &RegisteredSignalInfo[NumRegisteredSignals].SA); - RegisteredSignalInfo[NumRegisteredSignals].SigNo = Signal; - ++NumRegisteredSignals; -} - -static void RegisterHandlers() { - // If the handlers are already registered, we're done. - if (NumRegisteredSignals != 0) return; - - std::for_each(IntSigs, IntSigsEnd, RegisterHandler); - std::for_each(KillSigs, KillSigsEnd, RegisterHandler); -} - -static void UnregisterHandlers() { - // Restore all of the signal handlers to how they were before we showed up. - for (unsigned i = 0, e = NumRegisteredSignals; i != e; ++i) - sigaction(RegisteredSignalInfo[i].SigNo, - &RegisteredSignalInfo[i].SA, 0); - NumRegisteredSignals = 0; -} - - -/// RemoveFilesToRemove - Process the FilesToRemove list. This function -/// should be called with the SignalsMutex lock held. -static void RemoveFilesToRemove() { - while (!FilesToRemove.empty()) { - FilesToRemove.back().eraseFromDisk(true); - FilesToRemove.pop_back(); - } -} - -// SignalHandler - The signal handler that runs. -static RETSIGTYPE SignalHandler(int Sig) { - // Restore the signal behavior to default, so that the program actually - // crashes when we return and the signal reissues. This also ensures that if - // we crash in our signal handler that the program will terminate immediately - // instead of recursing in the signal handler. - UnregisterHandlers(); - - // Unmask all potentially blocked kill signals. - sigset_t SigMask; - sigfillset(&SigMask); - sigprocmask(SIG_UNBLOCK, &SigMask, 0); - - SignalsMutex.acquire(); - RemoveFilesToRemove(); - - if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd) { - if (InterruptFunction) { - void (*IF)() = InterruptFunction; - SignalsMutex.release(); - InterruptFunction = 0; - IF(); // run the interrupt function. - return; - } - - SignalsMutex.release(); - raise(Sig); // Execute the default handler. - return; - } - - SignalsMutex.release(); - - // Otherwise if it is a fault (like SEGV) run any handler. - for (unsigned i = 0, e = CallBacksToRun.size(); i != e; ++i) - CallBacksToRun[i].first(CallBacksToRun[i].second); -} - -void llvm::sys::RunInterruptHandlers() { - SignalsMutex.acquire(); - RemoveFilesToRemove(); - SignalsMutex.release(); -} - -void llvm::sys::SetInterruptFunction(void (*IF)()) { - SignalsMutex.acquire(); - InterruptFunction = IF; - SignalsMutex.release(); - RegisterHandlers(); -} - -// RemoveFileOnSignal - The public API -bool llvm::sys::RemoveFileOnSignal(const sys::Path &Filename, - std::string* ErrMsg) { - SignalsMutex.acquire(); - FilesToRemove.push_back(Filename); - - SignalsMutex.release(); - - RegisterHandlers(); - return false; -} - -// DontRemoveFileOnSignal - The public API -void llvm::sys::DontRemoveFileOnSignal(const sys::Path &Filename) { - SignalsMutex.acquire(); - std::vector<sys::Path>::reverse_iterator I = - std::find(FilesToRemove.rbegin(), FilesToRemove.rend(), Filename); - if (I != FilesToRemove.rend()) - FilesToRemove.erase(I.base()-1); - SignalsMutex.release(); -} - -/// AddSignalHandler - Add a function to be called when a signal is delivered -/// 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) { - CallBacksToRun.push_back(std::make_pair(FnPtr, Cookie)); - RegisterHandlers(); -} - - -// PrintStackTrace - In the case of a program crash or fault, print out a stack -// trace so that the user has an indication of why and where we died. -// -// On glibc systems we have the 'backtrace' function, which works nicely, but -// doesn't demangle symbols. -static void PrintStackTrace(void *) { -#ifdef HAVE_BACKTRACE - static void* StackTrace[256]; - // Use backtrace() to output a backtrace on Linux systems with glibc. - int depth = backtrace(StackTrace, - static_cast<int>(array_lengthof(StackTrace))); -#if HAVE_DLFCN_H && __GNUG__ - int width = 0; - for (int i = 0; i < depth; ++i) { - Dl_info dlinfo; - dladdr(StackTrace[i], &dlinfo); - const char* name = strrchr(dlinfo.dli_fname, '/'); - - int nwidth; - if (name == NULL) nwidth = strlen(dlinfo.dli_fname); - else nwidth = strlen(name) - 1; - - if (nwidth > width) width = nwidth; - } - - for (int i = 0; i < depth; ++i) { - Dl_info dlinfo; - dladdr(StackTrace[i], &dlinfo); - - fprintf(stderr, "%-2d", i); - - const char* name = strrchr(dlinfo.dli_fname, '/'); - if (name == NULL) fprintf(stderr, " %-*s", width, dlinfo.dli_fname); - else fprintf(stderr, " %-*s", width, name+1); - - fprintf(stderr, " %#0*lx", - (int)(sizeof(void*) * 2) + 2, (unsigned long)StackTrace[i]); - - if (dlinfo.dli_sname != NULL) { - int res; - fputc(' ', stderr); - char* d = abi::__cxa_demangle(dlinfo.dli_sname, NULL, NULL, &res); - if (d == NULL) fputs(dlinfo.dli_sname, stderr); - else fputs(d, stderr); - free(d); - - fprintf(stderr, " + %tu",(char*)StackTrace[i]-(char*)dlinfo.dli_saddr); - } - fputc('\n', stderr); - } -#else - backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO); -#endif -#endif -} - -/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or -/// SIGSEGV) is delivered to the process, print a stack trace and then exit. -void llvm::sys::PrintStackTraceOnErrorSignal() { - AddSignalHandler(PrintStackTrace, 0); -} - - -/***/ - -// On Darwin, raise sends a signal to the main thread instead of the current -// thread. This has the unfortunate effect that assert() and abort() will end up -// bypassing our crash recovery attempts. We work around this for anything in -// the same linkage unit by just defining our own versions of the assert handler -// and abort. - -#ifdef __APPLE__ - -void __assert_rtn(const char *func, - const char *file, - int line, - const char *expr) { - if (func) - fprintf(stderr, "Assertion failed: (%s), function %s, file %s, line %d.\n", - expr, func, file, line); - else - fprintf(stderr, "Assertion failed: (%s), file %s, line %d.\n", - expr, file, line); - abort(); -} - -#include <signal.h> -#include <pthread.h> - -void abort() { - pthread_kill(pthread_self(), SIGABRT); - usleep(1000); - __builtin_trap(); -} - -#endif diff --git a/lib/System/Unix/ThreadLocal.inc b/lib/System/Unix/ThreadLocal.inc deleted file mode 100644 index 6769520..0000000 --- a/lib/System/Unix/ThreadLocal.inc +++ /dev/null @@ -1,26 +0,0 @@ -//=== llvm/System/Unix/ThreadLocal.inc - Unix Thread Local Data -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Unix specific (non-pthread) ThreadLocal class. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic UNIX code that -//=== is guaranteed to work on *all* UNIX variants. -//===----------------------------------------------------------------------===// - -namespace llvm { -using namespace sys; -ThreadLocalImpl::ThreadLocalImpl() { } -ThreadLocalImpl::~ThreadLocalImpl() { } -void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);} -const void* ThreadLocalImpl::getInstance() { return data; } -void ThreadLocalImpl::removeInstance() { setInstance(0); } -} diff --git a/lib/System/Unix/TimeValue.inc b/lib/System/Unix/TimeValue.inc deleted file mode 100644 index d8cc8f5..0000000 --- a/lib/System/Unix/TimeValue.inc +++ /dev/null @@ -1,56 +0,0 @@ -//===- Unix/TimeValue.cpp - Unix TimeValue Implementation -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Unix specific portion of the TimeValue class. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic UNIX code that -//=== is guaranteed to work on *all* UNIX variants. -//===----------------------------------------------------------------------===// - -#include "Unix.h" - -namespace llvm { - using namespace sys; - -std::string TimeValue::str() const { - char buffer[32]; - - time_t ourTime = time_t(this->toEpochTime()); -#ifdef __hpux -// note that the following line needs -D_REENTRANT on HP-UX to be picked up - asctime_r(localtime(&ourTime), buffer); -#else - ::asctime_r(::localtime(&ourTime), buffer); -#endif - - std::string result(buffer); - return result.substr(0,24); -} - -TimeValue TimeValue::now() { - struct timeval the_time; - timerclear(&the_time); - if (0 != ::gettimeofday(&the_time,0)) { - // This is *really* unlikely to occur because the only gettimeofday - // errors concern the timezone parameter which we're passing in as 0. - // In the unlikely case it does happen, just return MinTime, no error - // message needed. - return MinTime; - } - - return TimeValue( - static_cast<TimeValue::SecondsType>( the_time.tv_sec + PosixZeroTime.seconds_ ), - static_cast<TimeValue::NanoSecondsType>( the_time.tv_usec * - NANOSECONDS_PER_MICROSECOND ) ); -} - -} diff --git a/lib/System/Unix/Unix.h b/lib/System/Unix/Unix.h deleted file mode 100644 index c15866f..0000000 --- a/lib/System/Unix/Unix.h +++ /dev/null @@ -1,87 +0,0 @@ -//===- llvm/System/Unix/Unix.h - Common Unix Include File -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines things specific to Unix implementations. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SYSTEM_UNIX_UNIX_H -#define LLVM_SYSTEM_UNIX_UNIX_H - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic UNIX code that -//=== is guaranteed to work on all UNIX variants. -//===----------------------------------------------------------------------===// - -#include "llvm/Config/config.h" // Get autoconf configuration settings -#include "llvm/System/Errno.h" -#include <cstdlib> -#include <cstdio> -#include <cstring> -#include <cerrno> -#include <string> -#include <algorithm> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif - -#ifdef HAVE_ASSERT_H -#include <assert.h> -#endif - -#ifdef TIME_WITH_SYS_TIME -# include <sys/time.h> -# include <time.h> -#else -# ifdef HAVE_SYS_TIME_H -# include <sys/time.h> -# else -# include <time.h> -# endif -#endif - -#ifdef HAVE_SYS_WAIT_H -# include <sys/wait.h> -#endif - -#ifndef WEXITSTATUS -# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) -#endif - -#ifndef WIFEXITED -# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -#endif - -/// This function builds an error message into \p ErrMsg using the \p prefix -/// string and the Unix error number given by \p errnum. If errnum is -1, the -/// default then the value of errno is used. -/// @brief Make an error message -/// -/// If the error number can be converted to a string, it will be -/// separated from prefix by ": ". -static inline bool MakeErrMsg( - std::string* ErrMsg, const std::string& prefix, int errnum = -1) { - if (!ErrMsg) - return true; - if (errnum == -1) - errnum = errno; - *ErrMsg = prefix + ": " + llvm::sys::StrError(errnum); - return true; -} - -#endif diff --git a/lib/System/Valgrind.cpp b/lib/System/Valgrind.cpp deleted file mode 100644 index c76cfe4..0000000 --- a/lib/System/Valgrind.cpp +++ /dev/null @@ -1,54 +0,0 @@ -//===-- 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/Alarm.inc b/lib/System/Win32/Alarm.inc deleted file mode 100644 index e0d00a0..0000000 --- a/lib/System/Win32/Alarm.inc +++ /dev/null @@ -1,43 +0,0 @@ -//===-- Alarm.inc - Implement Win32 Alarm Support ---------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Win32 Alarm support. -// -//===----------------------------------------------------------------------===// - -#include <cassert> -using namespace llvm; - -/// NestedSOI - Sanity check. Alarms cannot be nested or run in parallel. -/// This ensures that they never do. -static bool NestedSOI = false; - -void sys::SetupAlarm(unsigned seconds) { - assert(!NestedSOI && "sys::SetupAlarm calls cannot be nested!"); - NestedSOI = true; - // FIXME: Implement for Win32 -} - -void sys::TerminateAlarm() { - assert(NestedSOI && "sys::TerminateAlarm called without sys::SetupAlarm!"); - // FIXME: Implement for Win32 - NestedSOI = false; -} - -int sys::AlarmStatus() { - // FIXME: Implement for Win32 - return 0; -} - -// Don't pull in all of the Windows headers. -extern "C" void __stdcall Sleep(unsigned long); - -void sys::Sleep(unsigned n) { - ::Sleep(n*1000); -} diff --git a/lib/System/Win32/DynamicLibrary.inc b/lib/System/Win32/DynamicLibrary.inc deleted file mode 100644 index c9a89e5..0000000 --- a/lib/System/Win32/DynamicLibrary.inc +++ /dev/null @@ -1,200 +0,0 @@ -//===- Win32/DynamicLibrary.cpp - Win32 DL Implementation -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides the Win32 specific implementation of DynamicLibrary. -// -//===----------------------------------------------------------------------===// - -#include "Win32.h" - -#ifdef __MINGW32__ - #include <imagehlp.h> -#else - #include <dbghelp.h> -#endif - -#ifdef _MSC_VER - #include <ntverp.h> -#endif - -#ifdef __MINGW32__ - #if (HAVE_LIBIMAGEHLP != 1) - #error "libimagehlp.a should be present" - #endif -#else - #pragma comment(lib, "dbghelp.lib") -#endif - -namespace llvm { -using namespace sys; - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only Win32 specific code -//=== and must not be UNIX code. -//===----------------------------------------------------------------------===// - -static std::vector<HMODULE> OpenedHandles; - -#ifdef _WIN64 - typedef DWORD64 ModuleBaseType; -#else - typedef ULONG ModuleBaseType; -#endif - -extern "C" { -// Use old callback if: -// - Not using Visual Studio -// - Visual Studio 2005 or earlier but only if we are not using the Windows SDK -// or Windows SDK version is older than 6.0 -// Use new callback if: -// - Newer Visual Studio (comes with newer SDK). -// - Visual Studio 2005 with Windows SDK 6.0+ -#if !defined(_MSC_VER) || _MSC_VER < 1500 && (!defined(VER_PRODUCTBUILD) || VER_PRODUCTBUILD < 6000) - static BOOL CALLBACK ELM_Callback(PSTR ModuleName, - ModuleBaseType ModuleBase, - ULONG ModuleSize, - PVOID UserContext) -#else - static BOOL CALLBACK ELM_Callback(PCSTR ModuleName, - ModuleBaseType ModuleBase, - ULONG ModuleSize, - PVOID UserContext) -#endif - { - // Ignore VC++ runtimes prior to 7.1. Somehow some of them get loaded - // into the process. - if (stricmp(ModuleName, "msvci70") != 0 && - stricmp(ModuleName, "msvcirt") != 0 && - stricmp(ModuleName, "msvcp50") != 0 && - stricmp(ModuleName, "msvcp60") != 0 && - stricmp(ModuleName, "msvcp70") != 0 && - stricmp(ModuleName, "msvcr70") != 0 && -#ifndef __MINGW32__ - // Mingw32 uses msvcrt.dll by default. Don't ignore it. - // Otherwise, user should be aware, what he's doing :) - stricmp(ModuleName, "msvcrt") != 0 && -#endif - stricmp(ModuleName, "msvcrt20") != 0 && - stricmp(ModuleName, "msvcrt40") != 0) { - OpenedHandles.push_back((HMODULE)ModuleBase); - } - return TRUE; - } -} - -bool DynamicLibrary::LoadLibraryPermanently(const char *filename, - std::string *ErrMsg) { - if (filename) { - HMODULE a_handle = LoadLibrary(filename); - - if (a_handle == 0) - return MakeErrMsg(ErrMsg, std::string(filename) + ": Can't open : "); - - OpenedHandles.push_back(a_handle); - } else { - // When no file is specified, enumerate all DLLs and EXEs in the - // process. - EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0); - } - - // Because we don't remember the handle, we will never free it; hence, - // it is loaded permanently. - return false; -} - -// Stack probing routines are in the support library (e.g. libgcc), but we don't -// have dynamic linking on windows. Provide a hook. -#if defined(__MINGW32__) || defined (_MSC_VER) - #define EXPLICIT_SYMBOL(SYM) \ - if (!strcmp(symbolName, #SYM)) return (void*)&SYM - #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \ - if (!strcmp(symbolName, #SYMFROM)) return (void*)&SYMTO - #define EXPLICIT_SYMBOL_DEF(SYM) \ - extern "C" { extern void *SYM; } - - #if defined(__MINGW32__) - EXPLICIT_SYMBOL_DEF(_alloca) - EXPLICIT_SYMBOL_DEF(__main) - EXPLICIT_SYMBOL_DEF(__ashldi3) - EXPLICIT_SYMBOL_DEF(__ashrdi3) - EXPLICIT_SYMBOL_DEF(__cmpdi2) - EXPLICIT_SYMBOL_DEF(__divdi3) - EXPLICIT_SYMBOL_DEF(__fixdfdi) - EXPLICIT_SYMBOL_DEF(__fixsfdi) - EXPLICIT_SYMBOL_DEF(__fixunsdfdi) - EXPLICIT_SYMBOL_DEF(__fixunssfdi) - EXPLICIT_SYMBOL_DEF(__floatdidf) - EXPLICIT_SYMBOL_DEF(__floatdisf) - EXPLICIT_SYMBOL_DEF(__lshrdi3) - EXPLICIT_SYMBOL_DEF(__moddi3) - EXPLICIT_SYMBOL_DEF(__udivdi3) - EXPLICIT_SYMBOL_DEF(__umoddi3) - #elif defined(_MSC_VER) - EXPLICIT_SYMBOL_DEF(_alloca_probe) - #endif -#endif - -void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { - // First check symbols added via AddSymbol(). - if (ExplicitSymbols) { - std::map<std::string, void *>::iterator I = - ExplicitSymbols->find(symbolName); - std::map<std::string, void *>::iterator E = ExplicitSymbols->end(); - if (I != E) - return I->second; - } - - // Now search the libraries. - for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(), - E = OpenedHandles.end(); I != E; ++I) { - FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName); - if (ptr) { - return (void *) ptr; - } - } - -#if defined(__MINGW32__) - { - EXPLICIT_SYMBOL(_alloca); - EXPLICIT_SYMBOL(__main); - EXPLICIT_SYMBOL(__ashldi3); - EXPLICIT_SYMBOL(__ashrdi3); - EXPLICIT_SYMBOL(__cmpdi2); - EXPLICIT_SYMBOL(__divdi3); - 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); - - EXPLICIT_SYMBOL2(alloca, _alloca); -#undef EXPLICIT_SYMBOL -#undef EXPLICIT_SYMBOL2 -#undef EXPLICIT_SYMBOL_DEF - } -#elif defined(_MSC_VER) - { - EXPLICIT_SYMBOL2(alloca, _alloca_probe); - EXPLICIT_SYMBOL2(_alloca, _alloca_probe); -#undef EXPLICIT_SYMBOL -#undef EXPLICIT_SYMBOL2 -#undef EXPLICIT_SYMBOL_DEF - } -#endif - - return 0; -} - -} - diff --git a/lib/System/Win32/Host.inc b/lib/System/Win32/Host.inc deleted file mode 100644 index 18f00f8..0000000 --- a/lib/System/Win32/Host.inc +++ /dev/null @@ -1,23 +0,0 @@ -//===- llvm/System/Win32/Host.inc -------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Win32 Host support. -// -//===----------------------------------------------------------------------===// - -#include "Win32.h" -#include <cstdio> -#include <string> - -using namespace llvm; - -std::string sys::getHostTriple() { - // FIXME: Adapt to running version. - return LLVM_HOSTTRIPLE; -} diff --git a/lib/System/Win32/Memory.inc b/lib/System/Win32/Memory.inc deleted file mode 100644 index 19fccbd..0000000 --- a/lib/System/Win32/Memory.inc +++ /dev/null @@ -1,73 +0,0 @@ -//===- Win32/Memory.cpp - Win32 Memory Implementation -----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides the Win32 specific implementation of various Memory -// management utilities -// -//===----------------------------------------------------------------------===// - -#include "Win32.h" -#include "llvm/System/DataTypes.h" -#include "llvm/System/Process.h" - -namespace llvm { -using namespace sys; - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only Win32 specific code -//=== and must not be UNIX code -//===----------------------------------------------------------------------===// - -MemoryBlock Memory::AllocateRWX(size_t NumBytes, - const MemoryBlock *NearBlock, - std::string *ErrMsg) { - if (NumBytes == 0) return MemoryBlock(); - - static const size_t pageSize = Process::GetPageSize(); - size_t NumPages = (NumBytes+pageSize-1)/pageSize; - - //FIXME: support NearBlock if ever needed on Win64. - - void *pa = VirtualAlloc(NULL, NumPages*pageSize, MEM_COMMIT, - PAGE_EXECUTE_READWRITE); - if (pa == NULL) { - MakeErrMsg(ErrMsg, "Can't allocate RWX Memory: "); - return MemoryBlock(); - } - - MemoryBlock result; - result.Address = pa; - result.Size = NumPages*pageSize; - return result; -} - -bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) { - if (M.Address == 0 || M.Size == 0) return false; - if (!VirtualFree(M.Address, 0, MEM_RELEASE)) - return MakeErrMsg(ErrMsg, "Can't release RWX Memory: "); - return false; -} - -bool Memory::setWritable(MemoryBlock &M, std::string *ErrMsg) { - return true; -} - -bool Memory::setExecutable(MemoryBlock &M, std::string *ErrMsg) { - return false; -} - -bool Memory::setRangeWritable(const void *Addr, size_t Size) { - return true; -} - -bool Memory::setRangeExecutable(const void *Addr, size_t Size) { - return false; -} - -} diff --git a/lib/System/Win32/Mutex.inc b/lib/System/Win32/Mutex.inc deleted file mode 100644 index 75f01fe..0000000 --- a/lib/System/Win32/Mutex.inc +++ /dev/null @@ -1,58 +0,0 @@ -//===- llvm/System/Win32/Mutex.inc - Win32 Mutex Implementation -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Win32 specific (non-pthread) Mutex class. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic Win32 code that -//=== is guaranteed to work on *all* Win32 variants. -//===----------------------------------------------------------------------===// - -#include "Win32.h" -#include "llvm/System/Mutex.h" - -namespace llvm { -using namespace sys; - -MutexImpl::MutexImpl(bool /*recursive*/) -{ - data_ = new CRITICAL_SECTION; - InitializeCriticalSection((LPCRITICAL_SECTION)data_); -} - -MutexImpl::~MutexImpl() -{ - DeleteCriticalSection((LPCRITICAL_SECTION)data_); - delete (LPCRITICAL_SECTION)data_; - data_ = 0; -} - -bool -MutexImpl::acquire() -{ - EnterCriticalSection((LPCRITICAL_SECTION)data_); - return true; -} - -bool -MutexImpl::release() -{ - LeaveCriticalSection((LPCRITICAL_SECTION)data_); - return true; -} - -bool -MutexImpl::tryacquire() -{ - return TryEnterCriticalSection((LPCRITICAL_SECTION)data_); -} - -} diff --git a/lib/System/Win32/Path.inc b/lib/System/Win32/Path.inc deleted file mode 100644 index 4a6dbd3..0000000 --- a/lib/System/Win32/Path.inc +++ /dev/null @@ -1,872 +0,0 @@ -//===- llvm/System/Win32/Path.cpp - Win32 Path Implementation ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -// Modified by Henrik Bach to comply with at least MinGW. -// Ported to Win32 by Jeff Cohen. -// -//===----------------------------------------------------------------------===// -// -// This file provides the Win32 specific implementation of the Path class. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic Win32 code that -//=== is guaranteed to work on *all* Win32 variants. -//===----------------------------------------------------------------------===// - -#include "Win32.h" -#include <malloc.h> -#include <cstdio> - -// We need to undo a macro defined in Windows.h, otherwise we won't compile: -#undef CopyFile -#undef GetCurrentDirectory - -// Windows happily accepts either forward or backward slashes, though any path -// returned by a Win32 API will have backward slashes. As LLVM code basically -// assumes forward slashes are used, backward slashs are converted where they -// can be introduced into a path. -// -// Another invariant is that a path ends with a slash if and only if the path -// is a root directory. Any other use of a trailing slash is stripped. Unlike -// in Unix, Windows has a rather complicated notion of a root path and this -// invariant helps simply the code. - -static void FlipBackSlashes(std::string& s) { - for (size_t i = 0; i < s.size(); i++) - if (s[i] == '\\') - s[i] = '/'; -} - -namespace llvm { -namespace sys { -const char PathSeparator = ';'; - -Path::Path(llvm::StringRef p) - : path(p) { - FlipBackSlashes(path); -} - -Path::Path(const char *StrStart, unsigned StrLen) - : path(StrStart, StrLen) { - FlipBackSlashes(path); -} - -Path& -Path::operator=(StringRef that) { - path.assign(that.data(), that.size()); - FlipBackSlashes(path); - return *this; -} - -bool -Path::isValid() const { - if (path.empty()) - return false; - - // If there is a colon, it must be the second character, preceded by a letter - // and followed by something. - size_t len = path.size(); - size_t pos = path.rfind(':',len); - size_t rootslash = 0; - if (pos != std::string::npos) { - if (pos != 1 || !isalpha(path[0]) || len < 3) - return false; - rootslash = 2; - } - - // Look for a UNC path, and if found adjust our notion of the root slash. - if (len > 3 && path[0] == '/' && path[1] == '/') { - rootslash = path.find('/', 2); - if (rootslash == std::string::npos) - rootslash = 0; - } - - // Check for illegal characters. - if (path.find_first_of("\\<>\"|\001\002\003\004\005\006\007\010\011\012" - "\013\014\015\016\017\020\021\022\023\024\025\026" - "\027\030\031\032\033\034\035\036\037") - != std::string::npos) - return false; - - // Remove trailing slash, unless it's a root slash. - if (len > rootslash+1 && path[len-1] == '/') - path.erase(--len); - - // Check each component for legality. - for (pos = 0; pos < len; ++pos) { - // A component may not end in a space. - if (path[pos] == ' ') { - if (path[pos+1] == '/' || path[pos+1] == '\0') - return false; - } - - // A component may not end in a period. - if (path[pos] == '.') { - if (path[pos+1] == '/' || path[pos+1] == '\0') { - // Unless it is the pseudo-directory "."... - if (pos == 0 || path[pos-1] == '/' || path[pos-1] == ':') - return true; - // or "..". - if (pos > 0 && path[pos-1] == '.') { - if (pos == 1 || path[pos-2] == '/' || path[pos-2] == ':') - return true; - } - return false; - } - } - } - - return true; -} - -void Path::makeAbsolute() { - TCHAR FullPath[MAX_PATH + 1] = {0}; - LPTSTR FilePart = NULL; - - DWORD RetLength = ::GetFullPathNameA(path.c_str(), - sizeof(FullPath)/sizeof(FullPath[0]), - FullPath, &FilePart); - - if (0 == RetLength) { - // FIXME: Report the error GetLastError() - assert(0 && "Unable to make absolute path!"); - } else if (RetLength > MAX_PATH) { - // FIXME: Report too small buffer (needed RetLength bytes). - assert(0 && "Unable to make absolute path!"); - } else { - path = FullPath; - } -} - -bool -Path::isAbsolute(const char *NameStart, unsigned NameLen) { - assert(NameStart); - // FIXME: This does not handle correctly an absolute path starting from - // a drive letter or in UNC format. - switch (NameLen) { - case 0: - return false; - case 1: - case 2: - return NameStart[0] == '/'; - default: - return (NameStart[0] == '/' || (NameStart[1] == ':' && NameStart[2] == '/')) || - (NameStart[0] == '\\' || (NameStart[1] == ':' && NameStart[2] == '\\')); - } -} - -bool -Path::isAbsolute() const { - // FIXME: This does not handle correctly an absolute path starting from - // a drive letter or in UNC format. - switch (path.length()) { - case 0: - return false; - case 1: - case 2: - return path[0] == '/'; - default: - return path[0] == '/' || (path[1] == ':' && path[2] == '/'); - } -} - -static Path *TempDirectory; - -Path -Path::GetTemporaryDirectory(std::string* ErrMsg) { - if (TempDirectory) - return *TempDirectory; - - char pathname[MAX_PATH]; - if (!GetTempPath(MAX_PATH, pathname)) { - if (ErrMsg) - *ErrMsg = "Can't determine temporary directory"; - return Path(); - } - - Path result; - result.set(pathname); - - // Append a subdirectory passed on our process id so multiple LLVMs don't - // step on each other's toes. -#ifdef __MINGW32__ - // Mingw's Win32 header files are broken. - sprintf(pathname, "LLVM_%u", unsigned(GetCurrentProcessId())); -#else - sprintf(pathname, "LLVM_%u", GetCurrentProcessId()); -#endif - result.appendComponent(pathname); - - // If there's a directory left over from a previous LLVM execution that - // happened to have the same process id, get rid of it. - result.eraseFromDisk(true); - - // And finally (re-)create the empty directory. - result.createDirectoryOnDisk(false); - TempDirectory = new Path(result); - return *TempDirectory; -} - -// FIXME: the following set of functions don't map to Windows very well. -Path -Path::GetRootDirectory() { - Path result; - result.set("C:/"); - return result; -} - -void -Path::GetSystemLibraryPaths(std::vector<sys::Path>& Paths) { - Paths.push_back(sys::Path("C:/WINDOWS/SYSTEM32")); - Paths.push_back(sys::Path("C:/WINDOWS")); -} - -void -Path::GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths) { - char * env_var = getenv("LLVM_LIB_SEARCH_PATH"); - if (env_var != 0) { - getPathList(env_var,Paths); - } -#ifdef LLVM_LIBDIR - { - Path tmpPath; - if (tmpPath.set(LLVM_LIBDIR)) - if (tmpPath.canRead()) - Paths.push_back(tmpPath); - } -#endif - GetSystemLibraryPaths(Paths); -} - -Path -Path::GetLLVMDefaultConfigDir() { - // TODO: this isn't going to fly on Windows - return Path("/etc/llvm"); -} - -Path -Path::GetUserHomeDirectory() { - // TODO: Typical Windows setup doesn't define HOME. - const char* home = getenv("HOME"); - if (home) { - Path result; - if (result.set(home)) - return result; - } - return GetRootDirectory(); -} - -Path -Path::GetCurrentDirectory() { - char pathname[MAX_PATH]; - ::GetCurrentDirectoryA(MAX_PATH,pathname); - return Path(pathname); -} - -/// GetMainExecutable - Return the path to the main executable, given the -/// value of argv[0] from program startup. -Path Path::GetMainExecutable(const char *argv0, void *MainAddr) { - char pathname[MAX_PATH]; - DWORD ret = ::GetModuleFileNameA(NULL, pathname, MAX_PATH); - return ret != MAX_PATH ? Path(pathname) : Path(); -} - - -// FIXME: the above set of functions don't map to Windows very well. - - -StringRef Path::getDirname() const { - return getDirnameCharSep(path, "/"); -} - -StringRef -Path::getBasename() const { - // Find the last slash - size_t slash = path.rfind('/'); - if (slash == std::string::npos) - slash = 0; - else - slash++; - - size_t dot = path.rfind('.'); - if (dot == std::string::npos || dot < slash) - return StringRef(path).substr(slash); - else - return StringRef(path).substr(slash, dot - slash); -} - -StringRef -Path::getSuffix() const { - // Find the last slash - size_t slash = path.rfind('/'); - if (slash == std::string::npos) - slash = 0; - else - slash++; - - size_t dot = path.rfind('.'); - if (dot == std::string::npos || dot < slash) - return StringRef(""); - else - return StringRef(path).substr(dot + 1); -} - -bool -Path::exists() const { - DWORD attr = GetFileAttributes(path.c_str()); - return attr != INVALID_FILE_ATTRIBUTES; -} - -bool -Path::isDirectory() const { - DWORD attr = GetFileAttributes(path.c_str()); - return (attr != INVALID_FILE_ATTRIBUTES) && - (attr & FILE_ATTRIBUTE_DIRECTORY); -} - -bool -Path::canRead() const { - // FIXME: take security attributes into account. - DWORD attr = GetFileAttributes(path.c_str()); - return attr != INVALID_FILE_ATTRIBUTES; -} - -bool -Path::canWrite() const { - // FIXME: take security attributes into account. - DWORD attr = GetFileAttributes(path.c_str()); - return (attr != INVALID_FILE_ATTRIBUTES) && !(attr & FILE_ATTRIBUTE_READONLY); -} - -bool -Path::canExecute() const { - // FIXME: take security attributes into account. - DWORD attr = GetFileAttributes(path.c_str()); - return attr != INVALID_FILE_ATTRIBUTES; -} - -bool -Path::isRegularFile() const { - if (isDirectory()) - return false; - return true; -} - -StringRef -Path::getLast() const { - // Find the last slash - size_t pos = path.rfind('/'); - - // Handle the corner cases - if (pos == std::string::npos) - return path; - - // If the last character is a slash, we have a root directory - if (pos == path.length()-1) - return path; - - // Return everything after the last slash - return StringRef(path).substr(pos+1); -} - -const FileStatus * -PathWithStatus::getFileStatus(bool update, std::string *ErrStr) const { - if (!fsIsValid || update) { - WIN32_FILE_ATTRIBUTE_DATA fi; - if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) { - MakeErrMsg(ErrStr, "getStatusInfo():" + std::string(path) + - ": Can't get status: "); - return 0; - } - - status.fileSize = fi.nFileSizeHigh; - status.fileSize <<= sizeof(fi.nFileSizeHigh)*8; - status.fileSize += fi.nFileSizeLow; - - status.mode = fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? 0555 : 0777; - status.user = 9999; // Not applicable to Windows, so... - status.group = 9999; // Not applicable to Windows, so... - - // FIXME: this is only unique if the file is accessed by the same file path. - // How do we do this for C:\dir\file and ..\dir\file ? Unix has inode - // numbers, but the concept doesn't exist in Windows. - status.uniqueID = 0; - for (unsigned i = 0; i < path.length(); ++i) - status.uniqueID += path[i]; - - ULARGE_INTEGER ui; - ui.LowPart = fi.ftLastWriteTime.dwLowDateTime; - ui.HighPart = fi.ftLastWriteTime.dwHighDateTime; - status.modTime.fromWin32Time(ui.QuadPart); - - status.isDir = fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; - fsIsValid = true; - } - return &status; -} - -bool Path::makeReadableOnDisk(std::string* ErrMsg) { - // All files are readable on Windows (ignoring security attributes). - return false; -} - -bool Path::makeWriteableOnDisk(std::string* ErrMsg) { - DWORD attr = GetFileAttributes(path.c_str()); - - // If it doesn't exist, we're done. - if (attr == INVALID_FILE_ATTRIBUTES) - return false; - - if (attr & FILE_ATTRIBUTE_READONLY) { - if (!SetFileAttributes(path.c_str(), attr & ~FILE_ATTRIBUTE_READONLY)) { - MakeErrMsg(ErrMsg, std::string(path) + ": Can't make file writable: "); - return true; - } - } - return false; -} - -bool Path::makeExecutableOnDisk(std::string* ErrMsg) { - // All files are executable on Windows (ignoring security attributes). - return false; -} - -bool -Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const { - WIN32_FILE_ATTRIBUTE_DATA fi; - if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) { - MakeErrMsg(ErrMsg, path + ": can't get status of file"); - return true; - } - - if (!(fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - if (ErrMsg) - *ErrMsg = path + ": not a directory"; - return true; - } - - result.clear(); - WIN32_FIND_DATA fd; - std::string searchpath = path; - if (path.size() == 0 || searchpath[path.size()-1] == '/') - searchpath += "*"; - else - searchpath += "/*"; - - HANDLE h = FindFirstFile(searchpath.c_str(), &fd); - if (h == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_FILE_NOT_FOUND) - return true; // not really an error, now is it? - MakeErrMsg(ErrMsg, path + ": Can't read directory: "); - return true; - } - - do { - if (fd.cFileName[0] == '.') - continue; - Path aPath(path); - aPath.appendComponent(&fd.cFileName[0]); - result.insert(aPath); - } while (FindNextFile(h, &fd)); - - DWORD err = GetLastError(); - FindClose(h); - if (err != ERROR_NO_MORE_FILES) { - SetLastError(err); - MakeErrMsg(ErrMsg, path + ": Can't read directory: "); - return true; - } - return false; -} - -bool -Path::set(StringRef a_path) { - if (a_path.empty()) - return false; - std::string save(path); - path = a_path; - FlipBackSlashes(path); - if (!isValid()) { - path = save; - return false; - } - return true; -} - -bool -Path::appendComponent(StringRef name) { - if (name.empty()) - return false; - std::string save(path); - if (!path.empty()) { - size_t last = path.size() - 1; - if (path[last] != '/') - path += '/'; - } - path += name; - if (!isValid()) { - path = save; - return false; - } - return true; -} - -bool -Path::eraseComponent() { - size_t slashpos = path.rfind('/',path.size()); - if (slashpos == path.size() - 1 || slashpos == std::string::npos) - return false; - std::string save(path); - path.erase(slashpos); - if (!isValid()) { - path = save; - return false; - } - return true; -} - -bool -Path::appendSuffix(StringRef suffix) { - std::string save(path); - path.append("."); - path.append(suffix); - if (!isValid()) { - path = save; - return false; - } - return true; -} - -bool -Path::eraseSuffix() { - size_t dotpos = path.rfind('.',path.size()); - size_t slashpos = path.rfind('/',path.size()); - if (dotpos != std::string::npos) { - if (slashpos == std::string::npos || dotpos > slashpos+1) { - std::string save(path); - path.erase(dotpos, path.size()-dotpos); - if (!isValid()) { - path = save; - return false; - } - return true; - } - } - return false; -} - -inline bool PathMsg(std::string* ErrMsg, const char* pathname, const char*msg) { - if (ErrMsg) - *ErrMsg = std::string(pathname) + ": " + std::string(msg); - return true; -} - -bool -Path::createDirectoryOnDisk(bool create_parents, std::string* ErrMsg) { - // Get a writeable copy of the path name - size_t len = path.length(); - char *pathname = reinterpret_cast<char *>(_alloca(len+2)); - path.copy(pathname, len); - pathname[len] = 0; - - // Make sure it ends with a slash. - if (len == 0 || pathname[len - 1] != '/') { - pathname[len] = '/'; - pathname[++len] = 0; - } - - // Determine starting point for initial / search. - char *next = pathname; - if (pathname[0] == '/' && pathname[1] == '/') { - // Skip host name. - next = strchr(pathname+2, '/'); - if (next == NULL) - return PathMsg(ErrMsg, pathname, "badly formed remote directory"); - - // Skip share name. - next = strchr(next+1, '/'); - if (next == NULL) - return PathMsg(ErrMsg, pathname,"badly formed remote directory"); - - next++; - if (*next == 0) - return PathMsg(ErrMsg, pathname, "badly formed remote directory"); - - } else { - if (pathname[1] == ':') - next += 2; // skip drive letter - if (*next == '/') - next++; // skip root directory - } - - // If we're supposed to create intermediate directories - if (create_parents) { - // Loop through the directory components until we're done - while (*next) { - next = strchr(next, '/'); - *next = 0; - if (!CreateDirectory(pathname, NULL) && - GetLastError() != ERROR_ALREADY_EXISTS) - return MakeErrMsg(ErrMsg, - std::string(pathname) + ": Can't create directory: "); - *next++ = '/'; - } - } else { - // Drop trailing slash. - pathname[len-1] = 0; - if (!CreateDirectory(pathname, NULL) && - GetLastError() != ERROR_ALREADY_EXISTS) { - return MakeErrMsg(ErrMsg, std::string(pathname) + ": Can't create directory: "); - } - } - return false; -} - -bool -Path::createFileOnDisk(std::string* ErrMsg) { - // Create the file - HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, - FILE_ATTRIBUTE_NORMAL, NULL); - if (h == INVALID_HANDLE_VALUE) - return MakeErrMsg(ErrMsg, path + ": Can't create file: "); - - CloseHandle(h); - return false; -} - -bool -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()) - return false; - - char *pathname = reinterpret_cast<char *>(_alloca(path.length()+3)); - int lastchar = path.length() - 1 ; - path.copy(pathname, lastchar+1); - - // Make path end with '/*'. - if (pathname[lastchar] != '/') - pathname[++lastchar] = '/'; - pathname[lastchar+1] = '*'; - pathname[lastchar+2] = 0; - - if (remove_contents) { - WIN32_FIND_DATA fd; - HANDLE h = FindFirstFile(pathname, &fd); - - // It's a bad idea to alter the contents of a directory while enumerating - // its contents. So build a list of its contents first, then destroy them. - - if (h != INVALID_HANDLE_VALUE) { - std::vector<Path> list; - - do { - if (strcmp(fd.cFileName, ".") == 0) - continue; - if (strcmp(fd.cFileName, "..") == 0) - continue; - - Path aPath(path); - aPath.appendComponent(&fd.cFileName[0]); - list.push_back(aPath); - } while (FindNextFile(h, &fd)); - - DWORD err = GetLastError(); - FindClose(h); - if (err != ERROR_NO_MORE_FILES) { - SetLastError(err); - return MakeErrMsg(ErrStr, path + ": Can't read directory: "); - } - - for (std::vector<Path>::iterator I = list.begin(); I != list.end(); - ++I) { - Path &aPath = *I; - aPath.eraseFromDisk(true); - } - } else { - if (GetLastError() != ERROR_FILE_NOT_FOUND) - return MakeErrMsg(ErrStr, path + ": Can't read directory: "); - } - } - - pathname[lastchar] = 0; - if (!RemoveDirectory(pathname)) - return MakeErrMsg(ErrStr, - std::string(pathname) + ": Can't destroy directory: "); - return false; - } else { - // Read-only files cannot be deleted on Windows. Must remove the read-only - // attribute first. - if (fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { - if (!SetFileAttributes(path.c_str(), - fi.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY)) - return MakeErrMsg(ErrStr, path + ": Can't destroy file: "); - } - - if (!DeleteFile(path.c_str())) - return MakeErrMsg(ErrStr, path + ": Can't destroy file: "); - return false; - } -} - -bool Path::getMagicNumber(std::string& Magic, unsigned len) const { - assert(len < 1024 && "Request for magic string too long"); - char* buf = reinterpret_cast<char*>(alloca(len)); - - HANDLE h = CreateFile(path.c_str(), - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (h == INVALID_HANDLE_VALUE) - return false; - - DWORD nRead = 0; - BOOL ret = ReadFile(h, buf, len, &nRead, NULL); - CloseHandle(h); - - if (!ret || nRead != len) - return false; - - Magic = std::string(buf, len); - return true; -} - -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 false; -} - -bool -Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrMsg) const { - // FIXME: should work on directories also. - 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, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (h == INVALID_HANDLE_VALUE) - return true; - - BY_HANDLE_FILE_INFORMATION bhfi; - if (!GetFileInformationByHandle(h, &bhfi)) { - DWORD err = GetLastError(); - CloseHandle(h); - SetLastError(err); - return MakeErrMsg(ErrMsg, path + ": GetFileInformationByHandle: "); - } - - ULARGE_INTEGER ui; - ui.QuadPart = si.modTime.toWin32Time(); - FILETIME ft; - ft.dwLowDateTime = ui.LowPart; - ft.dwHighDateTime = ui.HighPart; - BOOL ret = SetFileTime(h, NULL, &ft, &ft); - DWORD err = GetLastError(); - CloseHandle(h); - if (!ret) { - SetLastError(err); - return MakeErrMsg(ErrMsg, path + ": SetFileTime: "); - } - - // Best we can do with Unix permission bits is to interpret the owner - // writable bit. - if (si.mode & 0200) { - if (bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { - if (!SetFileAttributes(path.c_str(), - bhfi.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY)) - return MakeErrMsg(ErrMsg, path + ": SetFileAttributes: "); - } - } else { - if (!(bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) { - if (!SetFileAttributes(path.c_str(), - bhfi.dwFileAttributes | FILE_ATTRIBUTE_READONLY)) - return MakeErrMsg(ErrMsg, path + ": SetFileAttributes: "); - } - } - - return false; -} - -bool -CopyFile(const sys::Path &Dest, const sys::Path &Src, std::string* ErrMsg) { - // Can't use CopyFile macro defined in Windows.h because it would mess up the - // above line. We use the expansion it would have in a non-UNICODE build. - if (!::CopyFileA(Src.c_str(), Dest.c_str(), false)) - return MakeErrMsg(ErrMsg, "Can't copy '" + Src.str() + - "' to '" + Dest.str() + "': "); - return false; -} - -bool -Path::makeUnique(bool reuse_current, std::string* ErrMsg) { - if (reuse_current && !exists()) - return false; // File doesn't exist already, just use it! - - // Reserve space for -XXXXXX at the end. - char *FNBuffer = (char*) alloca(path.size()+8); - unsigned offset = path.size(); - path.copy(FNBuffer, offset); - - // Find a numeric suffix that isn't used by an existing file. Assume there - // won't be more than 1 million files with the same prefix. Probably a safe - // bet. - static unsigned FCounter = 0; - do { - sprintf(FNBuffer+offset, "-%06u", FCounter); - if (++FCounter > 999999) - FCounter = 0; - path = FNBuffer; - } while (exists()); - return false; -} - -bool -Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) { - // Make this into a unique file name - makeUnique(reuse_current, ErrMsg); - - // Now go and create it - HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, - FILE_ATTRIBUTE_NORMAL, NULL); - if (h == INVALID_HANDLE_VALUE) - return MakeErrMsg(ErrMsg, path + ": can't create file"); - - CloseHandle(h); - return false; -} - -/// MapInFilePages - Not yet implemented on win32. -const char *Path::MapInFilePages(int FD, uint64_t FileSize) { - return 0; -} - -/// MapInFilePages - Not yet implemented on win32. -void Path::UnMapFilePages(const char *Base, uint64_t FileSize) { - assert(0 && "NOT IMPLEMENTED"); -} - -} -} diff --git a/lib/System/Win32/Process.inc b/lib/System/Win32/Process.inc deleted file mode 100644 index feb0806..0000000 --- a/lib/System/Win32/Process.inc +++ /dev/null @@ -1,221 +0,0 @@ -//===- Win32/Process.cpp - Win32 Process Implementation ------- -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides the Win32 specific implementation of the Process class. -// -//===----------------------------------------------------------------------===// - -#include "Win32.h" -#include <psapi.h> -#include <malloc.h> -#include <io.h> - -#ifdef __MINGW32__ - #if (HAVE_LIBPSAPI != 1) - #error "libpsapi.a should be present" - #endif -#else - #pragma comment(lib, "psapi.lib") -#endif - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only Win32 specific code -//=== and must not be UNIX code -//===----------------------------------------------------------------------===// - -#ifdef __MINGW32__ -// This ban should be lifted when MinGW 1.0+ has defined this value. -# define _HEAPOK (-2) -#endif - -namespace llvm { -using namespace sys; - -// This function retrieves the page size using GetSystemInfo and is present -// solely so it can be called once in Process::GetPageSize to initialize the -// static variable PageSize. -inline unsigned GetPageSizeOnce() { - // NOTE: A 32-bit application running under WOW64 is supposed to use - // GetNativeSystemInfo. However, this interface is not present prior - // to Windows XP so to use it requires dynamic linking. It is not clear - // how this affects the reported page size, if at all. One could argue - // that LLVM ought to run as 64-bits on a 64-bit system, anyway. - SYSTEM_INFO info; - GetSystemInfo(&info); - return static_cast<unsigned>(info.dwPageSize); -} - -unsigned -Process::GetPageSize() { - static const unsigned PageSize = GetPageSizeOnce(); - return PageSize; -} - -size_t -Process::GetMallocUsage() -{ - _HEAPINFO hinfo; - hinfo._pentry = NULL; - - size_t size = 0; - - while (_heapwalk(&hinfo) == _HEAPOK) - size += hinfo._size; - - return size; -} - -size_t -Process::GetTotalMemoryUsage() -{ - PROCESS_MEMORY_COUNTERS pmc; - GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)); - return pmc.PagefileUsage; -} - -void -Process::GetTimeUsage( - TimeValue& elapsed, TimeValue& user_time, TimeValue& sys_time) -{ - elapsed = TimeValue::now(); - - uint64_t ProcCreate, ProcExit, KernelTime, UserTime; - GetProcessTimes(GetCurrentProcess(), (FILETIME*)&ProcCreate, - (FILETIME*)&ProcExit, (FILETIME*)&KernelTime, - (FILETIME*)&UserTime); - - // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond) - user_time.seconds( UserTime / 10000000 ); - user_time.nanoseconds( unsigned(UserTime % 10000000) * 100 ); - sys_time.seconds( KernelTime / 10000000 ); - sys_time.nanoseconds( unsigned(KernelTime % 10000000) * 100 ); -} - -int Process::GetCurrentUserId() -{ - return 65536; -} - -int Process::GetCurrentGroupId() -{ - return 65536; -} - -// Some LLVM programs such as bugpoint produce core files as a normal part of -// their operation. To prevent the disk from filling up, this configuration item -// does what's necessary to prevent their generation. -void Process::PreventCoreFiles() { - // Windows doesn't do core files, but it does do modal pop-up message - // boxes. As this method is used by bugpoint, preventing these pop-ups - // is the moral equivalent of suppressing core files. - SetErrorMode(SEM_FAILCRITICALERRORS | - SEM_NOGPFAULTERRORBOX | - SEM_NOOPENFILEERRORBOX); -} - -bool Process::StandardInIsUserInput() { - return FileDescriptorIsDisplayed(0); -} - -bool Process::StandardOutIsDisplayed() { - return FileDescriptorIsDisplayed(1); -} - -bool Process::StandardErrIsDisplayed() { - return FileDescriptorIsDisplayed(2); -} - -bool Process::FileDescriptorIsDisplayed(int fd) { - return GetFileType((HANDLE)_get_osfhandle(fd)) == FILE_TYPE_CHAR; -} - -unsigned Process::StandardOutColumns() { - unsigned Columns = 0; - CONSOLE_SCREEN_BUFFER_INFO csbi; - if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) - Columns = csbi.dwSize.X; - return Columns; -} - -unsigned Process::StandardErrColumns() { - unsigned Columns = 0; - CONSOLE_SCREEN_BUFFER_INFO csbi; - if (GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &csbi)) - Columns = csbi.dwSize.X; - return Columns; -} - -// It always has colors. -bool Process::StandardErrHasColors() { - return StandardErrIsDisplayed(); -} - -bool Process::StandardOutHasColors() { - return StandardOutIsDisplayed(); -} - -namespace { -class DefaultColors -{ - private: - WORD defaultColor; - public: - DefaultColors() - :defaultColor(GetCurrentColor()) {} - static unsigned GetCurrentColor() { - CONSOLE_SCREEN_BUFFER_INFO csbi; - if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) - return csbi.wAttributes; - return 0; - } - WORD operator()() const { return defaultColor; } -}; - -DefaultColors defaultColors; -} - -bool Process::ColorNeedsFlush() { - return true; -} - -const char *Process::OutputBold(bool bg) { - WORD colors = DefaultColors::GetCurrentColor(); - if (bg) - colors |= BACKGROUND_INTENSITY; - else - colors |= FOREGROUND_INTENSITY; - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors); - return 0; -} - -const char *Process::OutputColor(char code, bool bold, bool bg) { - WORD colors; - if (bg) { - colors = ((code&1) ? BACKGROUND_RED : 0) | - ((code&2) ? BACKGROUND_GREEN : 0 ) | - ((code&4) ? BACKGROUND_BLUE : 0); - if (bold) - colors |= BACKGROUND_INTENSITY; - } else { - colors = ((code&1) ? FOREGROUND_RED : 0) | - ((code&2) ? FOREGROUND_GREEN : 0 ) | - ((code&4) ? FOREGROUND_BLUE : 0); - if (bold) - colors |= FOREGROUND_INTENSITY; - } - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors); - return 0; -} - -const char *Process::ResetColor() { - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), defaultColors()); - return 0; -} - -} diff --git a/lib/System/Win32/Program.inc b/lib/System/Win32/Program.inc deleted file mode 100644 index 16bb28e..0000000 --- a/lib/System/Win32/Program.inc +++ /dev/null @@ -1,409 +0,0 @@ -//===- Win32/Program.cpp - Win32 Program Implementation ------- -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides the Win32 specific implementation of the Program class. -// -//===----------------------------------------------------------------------===// - -#include "Win32.h" -#include <cstdio> -#include <malloc.h> -#include <io.h> -#include <fcntl.h> - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only Win32 specific code -//=== and must not be UNIX code -//===----------------------------------------------------------------------===// - -namespace { - struct Win32ProcessInfo { - HANDLE hProcess; - DWORD dwProcessId; - }; -} - -namespace llvm { -using namespace sys; - -Program::Program() : Data_(0) {} - -Program::~Program() { - if (Data_) { - Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_); - CloseHandle(wpi->hProcess); - delete wpi; - Data_ = 0; - } -} - -unsigned Program::GetPid() const { - Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_); - return wpi->dwProcessId; -} - -// This function just uses the PATH environment variable to find the program. -Path -Program::FindProgramByName(const std::string& progName) { - - // Check some degenerate cases - if (progName.length() == 0) // no program - return Path(); - Path temp; - if (!temp.set(progName)) // invalid name - return Path(); - if (temp.canExecute()) // already executable as is - return temp; - - // At this point, the file name is valid and its not executable. - // Let Windows search for it. - char buffer[MAX_PATH]; - char *dummy = NULL; - DWORD len = SearchPath(NULL, progName.c_str(), ".exe", MAX_PATH, - buffer, &dummy); - - // See if it wasn't found. - if (len == 0) - return Path(); - - // See if we got the entire path. - if (len < MAX_PATH) - return Path(buffer); - - // Buffer was too small; grow and retry. - while (true) { - char *b = reinterpret_cast<char *>(_alloca(len+1)); - DWORD len2 = SearchPath(NULL, progName.c_str(), ".exe", len+1, b, &dummy); - - // It is unlikely the search failed, but it's always possible some file - // was added or removed since the last search, so be paranoid... - if (len2 == 0) - return Path(); - else if (len2 <= len) - return Path(b); - - len = len2; - } -} - -static HANDLE RedirectIO(const Path *path, int fd, std::string* ErrMsg) { - HANDLE h; - if (path == 0) { - DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd), - GetCurrentProcess(), &h, - 0, TRUE, DUPLICATE_SAME_ACCESS); - return h; - } - - const char *fname; - if (path->isEmpty()) - fname = "NUL"; - else - fname = path->c_str(); - - SECURITY_ATTRIBUTES sa; - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = 0; - sa.bInheritHandle = TRUE; - - h = CreateFile(fname, fd ? GENERIC_WRITE : GENERIC_READ, FILE_SHARE_READ, - &sa, fd == 0 ? OPEN_EXISTING : CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); - if (h == INVALID_HANDLE_VALUE) { - MakeErrMsg(ErrMsg, std::string(fname) + ": Can't open file for " + - (fd ? "input: " : "output: ")); - } - - return h; -} - -#ifdef __MINGW32__ - // Due to unknown reason, mingw32's w32api doesn't have this declaration. - extern "C" - BOOL WINAPI SetInformationJobObject(HANDLE hJob, - JOBOBJECTINFOCLASS JobObjectInfoClass, - LPVOID lpJobObjectInfo, - DWORD cbJobObjectInfoLength); -#endif - -/// ArgNeedsQuotes - Check whether argument needs to be quoted when calling -/// CreateProcess. -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, - const char** envp, - const Path** redirects, - unsigned memoryLimit, - std::string* ErrMsg) { - if (Data_) { - Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_); - CloseHandle(wpi->hProcess); - delete wpi; - Data_ = 0; - } - - if (!path.canExecute()) { - if (ErrMsg) - *ErrMsg = "program not executable"; - return false; - } - - // Windows wants a command line, not an array of args, to pass to the new - // process. We have to concatenate them all, while quoting the args that - // have embedded spaces (or are empty). - - // First, determine the length of the command line. - unsigned len = 0; - for (unsigned i = 0; args[i]; i++) { - len += ArgLenWithQuotes(args[i]) + 1; - } - - // Now build the command line. - char *command = reinterpret_cast<char *>(_alloca(len+1)); - char *p = command; - - for (unsigned i = 0; args[i]; i++) { - const char *arg = args[i]; - - bool needsQuoting = ArgNeedsQuotes(arg); - if (needsQuoting) - *p++ = '"'; - - while (*arg != '\0') { - if (*arg == '\"') - *p++ = '\\'; - - *p++ = *arg++; - } - - if (needsQuoting) - *p++ = '"'; - *p++ = ' '; - } - - *p = 0; - - // The pointer to the environment block for the new process. - char *envblock = 0; - - if (envp) { - // An environment block consists of a null-terminated block of - // null-terminated strings. Convert the array of environment variables to - // an environment block by concatenating them. - - // First, determine the length of the environment block. - len = 0; - for (unsigned i = 0; envp[i]; i++) - len += strlen(envp[i]) + 1; - - // Now build the environment block. - envblock = reinterpret_cast<char *>(_alloca(len+1)); - p = envblock; - - for (unsigned i = 0; envp[i]; i++) { - const char *ev = envp[i]; - size_t len = strlen(ev) + 1; - memcpy(p, ev, len); - p += len; - } - - *p = 0; - } - - // Create a child process. - STARTUPINFO si; - memset(&si, 0, sizeof(si)); - si.cb = sizeof(si); - si.hStdInput = INVALID_HANDLE_VALUE; - si.hStdOutput = INVALID_HANDLE_VALUE; - si.hStdError = INVALID_HANDLE_VALUE; - - if (redirects) { - si.dwFlags = STARTF_USESTDHANDLES; - - si.hStdInput = RedirectIO(redirects[0], 0, ErrMsg); - if (si.hStdInput == INVALID_HANDLE_VALUE) { - MakeErrMsg(ErrMsg, "can't redirect stdin"); - return false; - } - si.hStdOutput = RedirectIO(redirects[1], 1, ErrMsg); - if (si.hStdOutput == INVALID_HANDLE_VALUE) { - CloseHandle(si.hStdInput); - MakeErrMsg(ErrMsg, "can't redirect stdout"); - return false; - } - if (redirects[1] && redirects[2] && *(redirects[1]) == *(redirects[2])) { - // If stdout and stderr should go to the same place, redirect stderr - // to the handle already open for stdout. - DuplicateHandle(GetCurrentProcess(), si.hStdOutput, - GetCurrentProcess(), &si.hStdError, - 0, TRUE, DUPLICATE_SAME_ACCESS); - } else { - // Just redirect stderr - si.hStdError = RedirectIO(redirects[2], 2, ErrMsg); - if (si.hStdError == INVALID_HANDLE_VALUE) { - CloseHandle(si.hStdInput); - CloseHandle(si.hStdOutput); - MakeErrMsg(ErrMsg, "can't redirect stderr"); - return false; - } - } - } - - PROCESS_INFORMATION pi; - memset(&pi, 0, sizeof(pi)); - - fflush(stdout); - fflush(stderr); - BOOL rc = CreateProcess(path.c_str(), command, NULL, NULL, TRUE, 0, - envblock, NULL, &si, &pi); - DWORD err = GetLastError(); - - // Regardless of whether the process got created or not, we are done with - // the handles we created for it to inherit. - CloseHandle(si.hStdInput); - CloseHandle(si.hStdOutput); - CloseHandle(si.hStdError); - - // Now return an error if the process didn't get created. - if (!rc) { - SetLastError(err); - MakeErrMsg(ErrMsg, std::string("Couldn't execute program '") + - path.str() + "'"); - return false; - } - Win32ProcessInfo* wpi = new Win32ProcessInfo; - wpi->hProcess = pi.hProcess; - wpi->dwProcessId = pi.dwProcessId; - Data_ = wpi; - - // Make sure these get closed no matter what. - AutoHandle hThread(pi.hThread); - - // Assign the process to a job if a memory limit is defined. - AutoHandle hJob(0); - if (memoryLimit != 0) { - hJob = CreateJobObject(0, 0); - bool success = false; - if (hJob != 0) { - JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli; - memset(&jeli, 0, sizeof(jeli)); - jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY; - jeli.ProcessMemoryLimit = uintptr_t(memoryLimit) * 1048576; - if (SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, - &jeli, sizeof(jeli))) { - if (AssignProcessToJobObject(hJob, pi.hProcess)) - success = true; - } - } - if (!success) { - SetLastError(GetLastError()); - MakeErrMsg(ErrMsg, std::string("Unable to set memory limit")); - TerminateProcess(pi.hProcess, 1); - WaitForSingleObject(pi.hProcess, INFINITE); - return false; - } - } - - return true; -} - -int -Program::Wait(unsigned secondsToWait, - std::string* ErrMsg) { - if (Data_ == 0) { - MakeErrMsg(ErrMsg, "Process not started!"); - return -1; - } - - Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_); - HANDLE hProcess = wpi->hProcess; - - // Wait for the process to terminate. - DWORD millisecondsToWait = INFINITE; - if (secondsToWait > 0) - millisecondsToWait = secondsToWait * 1000; - - if (WaitForSingleObject(hProcess, millisecondsToWait) == WAIT_TIMEOUT) { - if (!TerminateProcess(hProcess, 1)) { - MakeErrMsg(ErrMsg, "Failed to terminate timed-out program."); - return -1; - } - WaitForSingleObject(hProcess, INFINITE); - } - - // Get its exit status. - DWORD status; - BOOL rc = GetExitCodeProcess(hProcess, &status); - DWORD err = GetLastError(); - - if (!rc) { - SetLastError(err); - MakeErrMsg(ErrMsg, "Failed getting status for program."); - return -1; - } - - return status; -} - -bool -Program::Kill(std::string* ErrMsg) { - if (Data_ == 0) { - MakeErrMsg(ErrMsg, "Process not started!"); - return true; - } - - Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_); - HANDLE hProcess = wpi->hProcess; - if (TerminateProcess(hProcess, 1) == 0) { - MakeErrMsg(ErrMsg, "The process couldn't be killed!"); - return true; - } - - return false; -} - -bool Program::ChangeStdinToBinary(){ - int result = _setmode( _fileno(stdin), _O_BINARY ); - return result == -1; -} - -bool Program::ChangeStdoutToBinary(){ - int result = _setmode( _fileno(stdout), _O_BINARY ); - return result == -1; -} - -bool Program::ChangeStderrToBinary(){ - int result = _setmode( _fileno(stderr), _O_BINARY ); - return result == -1; -} - -} diff --git a/lib/System/Win32/RWMutex.inc b/lib/System/Win32/RWMutex.inc deleted file mode 100644 index e269226..0000000 --- a/lib/System/Win32/RWMutex.inc +++ /dev/null @@ -1,58 +0,0 @@ -//= llvm/System/Win32/Mutex.inc - Win32 Reader/Writer Mutual Exclusion Lock =// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Win32 specific (non-pthread) RWMutex class. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic Win32 code that -//=== is guaranteed to work on *all* Win32 variants. -//===----------------------------------------------------------------------===// - -#include "Win32.h" - -// FIXME: Windows does not have reader-writer locks pre-Vista. If you want -// real reader-writer locks, you a pthreads implementation for Windows. - -namespace llvm { -using namespace sys; - -RWMutexImpl::RWMutexImpl() { - data_ = calloc(1, sizeof(CRITICAL_SECTION)); - InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); -} - -RWMutexImpl::~RWMutexImpl() { - DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); - free(data_); -} - -bool RWMutexImpl::reader_acquire() { - EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); - return true; -} - -bool RWMutexImpl::reader_release() { - LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); - return true; -} - -bool RWMutexImpl::writer_acquire() { - EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); - return true; -} - -bool RWMutexImpl::writer_release() { - LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); - return true; -} - - -} diff --git a/lib/System/Win32/Signals.inc b/lib/System/Win32/Signals.inc deleted file mode 100644 index 2498a26e..0000000 --- a/lib/System/Win32/Signals.inc +++ /dev/null @@ -1,332 +0,0 @@ -//===- Win32/Signals.cpp - Win32 Signals Implementation ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides the Win32 specific implementation of the Signals class. -// -//===----------------------------------------------------------------------===// - -#include "Win32.h" -#include <stdio.h> -#include <vector> -#include <algorithm> - -#ifdef __MINGW32__ - #include <imagehlp.h> -#else - #include <dbghelp.h> -#endif -#include <psapi.h> - -#ifdef __MINGW32__ - #if ((HAVE_LIBIMAGEHLP != 1) || (HAVE_LIBPSAPI != 1)) - #error "libimagehlp.a & libpsapi.a should be present" - #endif -#else - #pragma comment(lib, "psapi.lib") - #pragma comment(lib, "dbghelp.lib") -#endif - -// Forward declare. -static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep); -static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType); - -// InterruptFunction - The function to call if ctrl-c is pressed. -static void (*InterruptFunction)() = 0; - -static std::vector<llvm::sys::Path> *FilesToRemove = NULL; -static std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0; -static bool RegisteredUnhandledExceptionFilter = false; -static bool CleanupExecuted = false; -#ifdef _MSC_VER -static bool ExitOnUnhandledExceptions = false; -#endif -static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL; - -// Windows creates a new thread to execute the console handler when an event -// (such as CTRL/C) occurs. This causes concurrency issues with the above -// globals which this critical section addresses. -static CRITICAL_SECTION CriticalSection; - -namespace llvm { - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only Win32 specific code -//=== and must not be UNIX code -//===----------------------------------------------------------------------===// - -#ifdef _MSC_VER -/// CRTReportHook - Function called on a CRT debugging event. -static int CRTReportHook(int ReportType, char *Message, int *Return) { - // Don't cause a DebugBreak() on return. - if (Return) - *Return = 0; - - switch (ReportType) { - default: - case _CRT_ASSERT: - fprintf(stderr, "CRT assert: %s\n", Message); - // FIXME: Is there a way to just crash? Perhaps throw to the unhandled - // exception code? Perhaps SetErrorMode() handles this. - _exit(3); - break; - case _CRT_ERROR: - fprintf(stderr, "CRT error: %s\n", Message); - // FIXME: Is there a way to just crash? Perhaps throw to the unhandled - // exception code? Perhaps SetErrorMode() handles this. - _exit(3); - break; - case _CRT_WARN: - fprintf(stderr, "CRT warn: %s\n", Message); - break; - } - - // Don't call _CrtDbgReport. - return TRUE; -} -#endif - -static void RegisterHandler() { - if (RegisteredUnhandledExceptionFilter) { - EnterCriticalSection(&CriticalSection); - return; - } - - // Now's the time to create the critical section. This is the first time - // through here, and there's only one thread. - InitializeCriticalSection(&CriticalSection); - - // Enter it immediately. Now if someone hits CTRL/C, the console handler - // can't proceed until the globals are updated. - EnterCriticalSection(&CriticalSection); - - RegisteredUnhandledExceptionFilter = true; - OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter); - SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE); - - // Environment variable to disable any kind of crash dialog. -#ifdef _MSC_VER - if (getenv("LLVM_DISABLE_CRT_DEBUG")) { - _CrtSetReportHook(CRTReportHook); - ExitOnUnhandledExceptions = true; - } -#endif - - // IMPORTANT NOTE: Caller must call LeaveCriticalSection(&CriticalSection) or - // else multi-threading problems will ensue. -} - -// RemoveFileOnSignal - The public API -bool sys::RemoveFileOnSignal(const sys::Path &Filename, std::string* ErrMsg) { - RegisterHandler(); - - if (CleanupExecuted) { - if (ErrMsg) - *ErrMsg = "Process terminating -- cannot register for removal"; - return true; - } - - if (FilesToRemove == NULL) - FilesToRemove = new std::vector<sys::Path>; - - FilesToRemove->push_back(Filename); - - LeaveCriticalSection(&CriticalSection); - return false; -} - -// DontRemoveFileOnSignal - The public API -void sys::DontRemoveFileOnSignal(const sys::Path &Filename) { - if (FilesToRemove == NULL) - return; - - FilesToRemove->push_back(Filename); - std::vector<sys::Path>::reverse_iterator I = - std::find(FilesToRemove->rbegin(), FilesToRemove->rend(), Filename); - if (I != FilesToRemove->rend()) - FilesToRemove->erase(I.base()-1); - - LeaveCriticalSection(&CriticalSection); -} - -/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or -/// SIGSEGV) is delivered to the process, print a stack trace and then exit. -void sys::PrintStackTraceOnErrorSignal() { - RegisterHandler(); - LeaveCriticalSection(&CriticalSection); -} - - -void sys::SetInterruptFunction(void (*IF)()) { - RegisterHandler(); - InterruptFunction = IF; - LeaveCriticalSection(&CriticalSection); -} - - -/// AddSignalHandler - Add a function to be called when a signal is delivered -/// to the process. The handler can have a cookie passed to it to identify -/// what instance of the handler it is. -void 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)); - RegisterHandler(); - LeaveCriticalSection(&CriticalSection); -} -} - -static void Cleanup() { - EnterCriticalSection(&CriticalSection); - - // Prevent other thread from registering new files and directories for - // removal, should we be executing because of the console handler callback. - CleanupExecuted = true; - - // FIXME: open files cannot be deleted. - - if (FilesToRemove != NULL) - while (!FilesToRemove->empty()) { - FilesToRemove->back().eraseFromDisk(); - FilesToRemove->pop_back(); - } - - if (CallBacksToRun) - for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i) - (*CallBacksToRun)[i].first((*CallBacksToRun)[i].second); - - LeaveCriticalSection(&CriticalSection); -} - -void llvm::sys::RunInterruptHandlers() { - Cleanup(); -} - -static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) { - try { - Cleanup(); - -#ifdef _WIN64 - // TODO: provide a x64 friendly version of the following -#else - - // Initialize the STACKFRAME structure. - STACKFRAME StackFrame; - memset(&StackFrame, 0, sizeof(StackFrame)); - - StackFrame.AddrPC.Offset = ep->ContextRecord->Eip; - StackFrame.AddrPC.Mode = AddrModeFlat; - StackFrame.AddrStack.Offset = ep->ContextRecord->Esp; - StackFrame.AddrStack.Mode = AddrModeFlat; - StackFrame.AddrFrame.Offset = ep->ContextRecord->Ebp; - StackFrame.AddrFrame.Mode = AddrModeFlat; - - HANDLE hProcess = GetCurrentProcess(); - HANDLE hThread = GetCurrentThread(); - - // Initialize the symbol handler. - SymSetOptions(SYMOPT_DEFERRED_LOADS|SYMOPT_LOAD_LINES); - SymInitialize(hProcess, NULL, TRUE); - - while (true) { - if (!StackWalk(IMAGE_FILE_MACHINE_I386, hProcess, hThread, &StackFrame, - ep->ContextRecord, NULL, SymFunctionTableAccess, - SymGetModuleBase, NULL)) { - break; - } - - if (StackFrame.AddrFrame.Offset == 0) - break; - - // Print the PC in hexadecimal. - DWORD PC = StackFrame.AddrPC.Offset; - fprintf(stderr, "%08lX", PC); - - // Print the parameters. Assume there are four. - fprintf(stderr, " (0x%08lX 0x%08lX 0x%08lX 0x%08lX)", StackFrame.Params[0], - StackFrame.Params[1], StackFrame.Params[2], StackFrame.Params[3]); - - // Verify the PC belongs to a module in this process. - if (!SymGetModuleBase(hProcess, PC)) { - fputs(" <unknown module>\n", stderr); - continue; - } - - // Print the symbol name. - char buffer[512]; - IMAGEHLP_SYMBOL *symbol = reinterpret_cast<IMAGEHLP_SYMBOL *>(buffer); - memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL)); - symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); - symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL); - - DWORD dwDisp; - if (!SymGetSymFromAddr(hProcess, PC, &dwDisp, symbol)) { - fputc('\n', stderr); - continue; - } - - buffer[511] = 0; - if (dwDisp > 0) - fprintf(stderr, ", %s()+%04lu bytes(s)", symbol->Name, dwDisp); - else - fprintf(stderr, ", %s", symbol->Name); - - // Print the source file and line number information. - IMAGEHLP_LINE line; - memset(&line, 0, sizeof(line)); - line.SizeOfStruct = sizeof(line); - if (SymGetLineFromAddr(hProcess, PC, &dwDisp, &line)) { - fprintf(stderr, ", %s, line %lu", line.FileName, line.LineNumber); - if (dwDisp > 0) - fprintf(stderr, "+%04lu byte(s)", dwDisp); - } - - fputc('\n', stderr); - } - -#endif - - } catch (...) { - assert(0 && "Crashed in LLVMUnhandledExceptionFilter"); - } - -#ifdef _MSC_VER - if (ExitOnUnhandledExceptions) - _exit(-3); -#endif - - // Allow dialog box to pop up allowing choice to start debugger. - if (OldFilter) - return (*OldFilter)(ep); - else - return EXCEPTION_CONTINUE_SEARCH; -} - -static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) { - // We are running in our very own thread, courtesy of Windows. - EnterCriticalSection(&CriticalSection); - Cleanup(); - - // If an interrupt function has been set, go and run one it; otherwise, - // the process dies. - void (*IF)() = InterruptFunction; - InterruptFunction = 0; // Don't run it on another CTRL-C. - - if (IF) { - // Note: if the interrupt function throws an exception, there is nothing - // to catch it in this thread so it will kill the process. - IF(); // Run it now. - LeaveCriticalSection(&CriticalSection); - return TRUE; // Don't kill the process. - } - - // Allow normal processing to take place; i.e., the process dies. - LeaveCriticalSection(&CriticalSection); - return FALSE; -} - diff --git a/lib/System/Win32/ThreadLocal.inc b/lib/System/Win32/ThreadLocal.inc deleted file mode 100644 index b8b933c..0000000 --- a/lib/System/Win32/ThreadLocal.inc +++ /dev/null @@ -1,53 +0,0 @@ -//= llvm/System/Win32/ThreadLocal.inc - Win32 Thread Local Data -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Win32 specific (non-pthread) ThreadLocal class. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic Win32 code that -//=== is guaranteed to work on *all* Win32 variants. -//===----------------------------------------------------------------------===// - -#include "Win32.h" -#include "llvm/System/ThreadLocal.h" - -namespace llvm { -using namespace sys; - -ThreadLocalImpl::ThreadLocalImpl() { - DWORD* tls = new DWORD; - *tls = TlsAlloc(); - assert(*tls != TLS_OUT_OF_INDEXES); - data = tls; -} - -ThreadLocalImpl::~ThreadLocalImpl() { - DWORD* tls = static_cast<DWORD*>(data); - TlsFree(*tls); - delete tls; -} - -const void* ThreadLocalImpl::getInstance() { - DWORD* tls = static_cast<DWORD*>(data); - return TlsGetValue(*tls); -} - -void ThreadLocalImpl::setInstance(const void* d){ - DWORD* tls = static_cast<DWORD*>(data); - int errorcode = TlsSetValue(*tls, const_cast<void*>(d)); - assert(errorcode != 0); -} - -void ThreadLocalImpl::removeInstance() { - setInstance(0); -} - -} diff --git a/lib/System/Win32/TimeValue.inc b/lib/System/Win32/TimeValue.inc deleted file mode 100644 index e37f111..0000000 --- a/lib/System/Win32/TimeValue.inc +++ /dev/null @@ -1,51 +0,0 @@ -//===- Win32/TimeValue.cpp - Win32 TimeValue Implementation -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides the Win32 implementation of the TimeValue class. -// -//===----------------------------------------------------------------------===// - -#include "Win32.h" -#include <time.h> - -namespace llvm { -using namespace sys; - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only Win32 specific code. -//===----------------------------------------------------------------------===// - -TimeValue TimeValue::now() { - uint64_t ft; - GetSystemTimeAsFileTime(reinterpret_cast<FILETIME *>(&ft)); - - TimeValue t(0, 0); - t.fromWin32Time(ft); - return t; -} - -std::string TimeValue::str() const { -#ifdef __MINGW32__ - // This ban may be lifted by either: - // (i) a future MinGW version other than 1.0 inherents the __time64_t type, or - // (ii) configure tests for either the time_t or __time64_t type. - time_t ourTime = time_t(this->toEpochTime()); - struct tm *lt = ::localtime(&ourTime); -#else - __time64_t ourTime = this->toEpochTime(); - struct tm *lt = ::_localtime64(&ourTime); -#endif - - char buffer[25]; - strftime(buffer, 25, "%a %b %d %H:%M:%S %Y", lt); - return std::string(buffer); -} - - -} diff --git a/lib/System/Win32/Win32.h b/lib/System/Win32/Win32.h deleted file mode 100644 index 8f505b1..0000000 --- a/lib/System/Win32/Win32.h +++ /dev/null @@ -1,57 +0,0 @@ -//===- Win32/Win32.h - Common Win32 Include File ----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines things specific to Win32 implementations. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic Win32 code that -//=== is guaranteed to work on *all* Win32 variants. -//===----------------------------------------------------------------------===// - -// Require at least Windows 2000 API. -#define _WIN32_WINNT 0x0500 - -#include "llvm/Config/config.h" // Get autoconf configuration settings -#include "windows.h" -#include <cassert> -#include <string> - -inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) { - if (!ErrMsg) - return true; - char *buffer = NULL; - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, - NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL); - *ErrMsg = prefix + buffer; - LocalFree(buffer); - return true; -} - -class AutoHandle { - HANDLE handle; - -public: - AutoHandle(HANDLE h) : handle(h) {} - - ~AutoHandle() { - if (handle) - CloseHandle(handle); - } - - operator HANDLE() { - return handle; - } - - AutoHandle &operator=(HANDLE h) { - handle = h; - return *this; - } -}; |