diff options
author | Michael J. Spencer <bigcheesegs@gmail.com> | 2010-11-29 18:16:10 +0000 |
---|---|---|
committer | Michael J. Spencer <bigcheesegs@gmail.com> | 2010-11-29 18:16:10 +0000 |
commit | 1f6efa3996dd1929fbc129203ce5009b620e6969 (patch) | |
tree | 6b782914982f90d3a983bcefef98b8ef68ab2961 /lib/Support | |
parent | 9363f739cdc3bd02e8516a25de0090f52ae12fbb (diff) |
Merge System into Support.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120298 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
69 files changed, 7414 insertions, 36 deletions
diff --git a/lib/Support/Alarm.cpp b/lib/Support/Alarm.cpp new file mode 100644 index 0000000000..58ad609cd2 --- /dev/null +++ b/lib/Support/Alarm.cpp @@ -0,0 +1,33 @@ +//===- 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/Support/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 "Windows/Alarm.inc" +#endif diff --git a/lib/Support/Allocator.cpp b/lib/Support/Allocator.cpp index 02b45d8af9..5e27df6628 100644 --- a/lib/Support/Allocator.cpp +++ b/lib/Support/Allocator.cpp @@ -12,10 +12,10 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Allocator.h" -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include "llvm/Support/Recycler.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/System/Memory.h" +#include "llvm/Support/Memory.h" #include <cstring> namespace llvm { diff --git a/lib/Support/Atomic.cpp b/lib/Support/Atomic.cpp new file mode 100644 index 0000000000..c7b4bff279 --- /dev/null +++ b/lib/Support/Atomic.cpp @@ -0,0 +1,112 @@ +//===-- 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/Support/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/Support/CMakeLists.txt b/lib/Support/CMakeLists.txt index 8a6ed6fa6d..105a507abd 100644 --- a/lib/Support/CMakeLists.txt +++ b/lib/Support/CMakeLists.txt @@ -1,5 +1,8 @@ ## FIXME: This only requires RTTI because tblgen uses it. Fix that. set(LLVM_REQUIRES_RTTI 1) +if( MINGW ) + set(LLVM_REQUIRES_EH 1) +endif() add_llvm_library(LLVMSupport APFloat.cpp @@ -49,4 +52,51 @@ add_llvm_library(LLVMSupport regexec.c regfree.c regstrlcpy.c + +# System + 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 + system_error.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/system_error.inc + Unix/ThreadLocal.inc + Unix/TimeValue.inc + Windows/Alarm.inc + Windows/DynamicLibrary.inc + Windows/Host.inc + Windows/Memory.inc + Windows/Mutex.inc + Windows/Path.inc + Windows/Process.inc + Windows/Program.inc + Windows/RWMutex.inc + Windows/Signals.inc + Windows/system_error.inc + Windows/ThreadLocal.inc + Windows/TimeValue.inc ) diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp index 38ef084961..a99e46dbd1 100644 --- a/lib/Support/CommandLine.cpp +++ b/lib/Support/CommandLine.cpp @@ -23,8 +23,8 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetRegistry.h" -#include "llvm/System/Host.h" -#include "llvm/System/Path.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/Path.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" diff --git a/lib/Support/CrashRecoveryContext.cpp b/lib/Support/CrashRecoveryContext.cpp index f24d6bdad8..bf8ca3f844 100644 --- a/lib/Support/CrashRecoveryContext.cpp +++ b/lib/Support/CrashRecoveryContext.cpp @@ -10,8 +10,8 @@ #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/ADT/SmallString.h" #include "llvm/Config/config.h" -#include "llvm/System/Mutex.h" -#include "llvm/System/ThreadLocal.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Support/ThreadLocal.h" #include <setjmp.h> #include <cstdio> using namespace llvm; diff --git a/lib/Support/Debug.cpp b/lib/Support/Debug.cpp index 7f48f8aae7..9fdb12ecfd 100644 --- a/lib/Support/Debug.cpp +++ b/lib/Support/Debug.cpp @@ -26,7 +26,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/circular_raw_ostream.h" -#include "llvm/System/Signals.h" +#include "llvm/Support/Signals.h" using namespace llvm; diff --git a/lib/Support/Disassembler.cpp b/lib/Support/Disassembler.cpp new file mode 100644 index 0000000000..6362aff43a --- /dev/null +++ b/lib/Support/Disassembler.cpp @@ -0,0 +1,75 @@ +//===- 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/Support/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/Support/DynamicLibrary.cpp b/lib/Support/DynamicLibrary.cpp new file mode 100644 index 0000000000..cd9927a193 --- /dev/null +++ b/lib/Support/DynamicLibrary.cpp @@ -0,0 +1,177 @@ +//===-- 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/Support/DynamicLibrary.h" +#include "llvm/Support/Mutex.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 "Windows/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 SmartMutex<true>* HandlesMutex; +static std::vector<void *> *OpenedHandles = 0; + +static bool InitializeMutex() { + HandlesMutex = new SmartMutex<true>; + return HandlesMutex != 0; +} + +static bool EnsureMutexInitialized() { + static bool result = InitializeMutex(); + return result; +} + + +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 + EnsureMutexInitialized(); + SmartScopedLock<true> Lock(*HandlesMutex); + 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. + EnsureMutexInitialized(); + SmartScopedLock<true> Lock(*HandlesMutex); + 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/Support/Errno.cpp b/lib/Support/Errno.cpp new file mode 100644 index 0000000000..312d91e063 --- /dev/null +++ b/< |