+Index: include/llvm/Support/DynamicLibrary.h
+===================================================================
+--- include/llvm/Support/DynamicLibrary.h	(revision 167609)
++++ include/llvm/Support/DynamicLibrary.h	(working copy)
+@@ -48,14 +48,19 @@ namespace sys {
+     /// Returns true if the object refers to a valid library.
+     bool isValid() { return Data != &Invalid; }
+ 
+-    /// Searches through the library for the symbol \p symbolName. If it is
++    /// Searches through the library for the symbol \p SymbolName. If it is
+     /// found, the address of that symbol is returned. If not, NULL is returned.
+     /// Note that NULL will also be returned if the library failed to load.
+     /// Use isValid() to distinguish these cases if it is important.
+     /// Note that this will \e not search symbols explicitly registered by
+     /// AddSymbol().
+-    void *getAddressOfSymbol(const char *symbolName);
++    void *getAddressOfSymbol(const char *SymbolName);
+ 
++    /// Unload the dynamic library. \p *errMsg will be set to an error message
++    /// if the library fails to unload. Returns true on success.
++    ///
++    bool Unload(std::string *ErrMsg = 0);
++
+     /// This function permanently loads the dynamic library at the given path.
+     /// The library will only be unloaded when the program terminates.
+     /// This returns a valid DynamicLibrary instance on success and an invalid
+@@ -64,8 +69,10 @@ namespace sys {
+     ///
+     /// It is safe to call this function multiple times for the same library.
+     /// @brief Open a dynamic library permanently.
+-    static DynamicLibrary getPermanentLibrary(const char *filename,
+-                                              std::string *errMsg = 0);
++    static DynamicLibrary getPermanentLibrary(const char *Filename,
++                                              std::string *ErrMsg = 0) {
++      return getLibrary(Filename, true /*permanent*/, ErrMsg);
++    }
+ 
+     /// This function permanently loads the dynamic library at the given path.
+     /// Use this instead of getPermanentLibrary() when you won't need to get
+@@ -77,25 +84,58 @@ namespace sys {
+       return !getPermanentLibrary(Filename, ErrMsg).isValid();
+     }
+ 
+-    /// This function will search through all previously loaded dynamic
+-    /// libraries for the symbol \p symbolName. If it is found, the address of
+-    /// that symbol is returned. If not, null is returned. Note that this will
+-    /// search permanently loaded libraries (getPermanentLibrary()) as well
+-    /// as explicitly registered symbols (AddSymbol()).
+-    /// @throws std::string on error.
+-    /// @brief Search through libraries for address of a symbol
+-    static void *SearchForAddressOfSymbol(const char *symbolName);
++    /// This function loads the dynamic library at the given path. If 
++    /// !permanent, the library can be unloaded by UnloadLibrary().
++    /// This returns a valid DynamicLibrary instance on success and an invalid
++    /// instance on failure (see isValid()). \p *errMsg will only be modified
++    /// if the library fails to load.
++    ///
++    /// It is safe to call this function multiple times for the same library.
++    /// @brief Open a dynamic library.
++    static DynamicLibrary getLibrary(const char *Filename,
++                                     bool Permanent = false,
++                                     std::string *ErrMsg = 0);
+ 
++    /// This function loads the dynamic library at the given path. If 
++    /// !permanent, the library can be unloaded by UnloadLibrary().
++    /// Use this instead of getLibrary() when you won't need to get
++    /// symbols from the library itself.
++    ///
++    /// It is safe to call this function multiple times for the same library.
++    static bool LoadLibrary(const char *Filename, bool Permanent = false,
++                            std::string *ErrMsg = 0) {
++      return !getLibrary(Filename, Permanent, ErrMsg).isValid();
++    }
++
++    /// Unload the dynamic library at the given path. \p *errMsg will be
++    /// set to an error message if the library fails to unload. Returns
++    /// true on success.
++    ///
++    static bool Unload(const char *Filename, std::string *ErrMsg = 0);
++
++    /// Search through all previously loaded dynamic libraries and explicitly
++    /// registered symbols (AddSymbol()) for the symbol \p symbolName. If it is
++    /// found, the address of that symbol is returned. If not, null is returned.
++    /// @brief Search through libraries and added symbols for address of a symbol
++    static void *SearchForAddressOfSymbol(const char *SymbolName);
++
+     /// @brief Convenience function for C++ophiles.
+-    static void *SearchForAddressOfSymbol(const std::string &symbolName) {
+-      return SearchForAddressOfSymbol(symbolName.c_str());
++    static void *SearchForAddressOfSymbol(const std::string &SymbolName) {
++      return SearchForAddressOfSymbol(SymbolName.c_str());
+     }
+ 
++    /// This function will search through all previously loaded dynamic
++    /// libraries for the symbol \p symbolName, but not through explicitly
++    /// provided symbols (AddSymbol()). If it is found, the address of
++    /// that symbol is returned. If not, null is returned.
++    /// @brief Search through libraries for address of a symbol
++    static void *SearchForLibrarySymbol(const char *SymbolName);
++
+     /// This functions permanently adds the symbol \p symbolName with the
+     /// value \p symbolValue.  These symbols are searched before any
+     /// libraries.
+     /// @brief Add searchable symbol/value pair.
+-    static void AddSymbol(StringRef symbolName, void *symbolValue);
++    static void AddSymbol(StringRef SymbolName, void *SymbolValue);
+   };
+ 
+ } // End sys namespace
+Index: lib/Support/DynamicLibrary.cpp
+===================================================================
+--- lib/Support/DynamicLibrary.cpp	(revision 167609)
++++ lib/Support/DynamicLibrary.cpp	(working copy)
+@@ -14,176 +14,226 @@
+ //===----------------------------------------------------------------------===//
+ 
+ #include "llvm/ADT/StringMap.h"
+-#include "llvm/ADT/DenseSet.h"
++#include "llvm/ADT/DenseMap.h"
+ #include "llvm/Support/DynamicLibrary.h"
+ #include "llvm/Support/Mutex.h"
+ #include "llvm/Config/config.h"
+ #include <cstdio>
+ #include <cstring>
+ 
+-// Collection of symbol name/value pairs to be searched prior to any libraries.
+-static llvm::StringMap<void *> *ExplicitSymbols = 0;
++using namespace llvm;
++using namespace llvm::sys;
+ 
++// Platform-specific implementations are required to define these function.
++// They do not need to be reentrant; locking is done by the caller.
++
++// Open the shared library called filename and return its handle. If filename
++// is NULL, return a handle for searching symbols in the whole process.
++static void *OpenLibraryImpl(const char *Filename, std::string *ErrMsg);
++// Close the shared library.
++static bool  CloseLibraryImpl(void *DlHandle, std::string *ErrMsg);
++// Get the address of the symbol named symname from the library with dlhandle.
++// Global is true if this is part of a search spanning all OpenedHandles.
++static void *GetAddressOfSymbolImpl(void *DlHandle, const char *SymbolName,
++                                    bool Global);
++// Inject special platform symbols into the map of explicitly defined symbols.
++static void PopulateSpecialSymbolsImpl(StringMap<void *>& SymMap);
++
+ namespace {
++struct SpecialSymbolHolder {
++  SpecialSymbolHolder() {
++    PopulateSpecialSymbolsImpl(Map);
++  }
+ 
++  // Symbol name/value pairs to be searched prior to any libraries.
++  StringMap<void *> Map;
++};
++}
++// Platform specific symbols, searched after libraries
++static SpecialSymbolHolder *SpecialSymbols = 0;
++
++// User provided symbols, searched before libraries
++static StringMap<void *> *ExplicitSymbols = 0;
++
++namespace {
+ struct ExplicitSymbolsDeleter {
+   ~ExplicitSymbolsDeleter() {
+     delete ExplicitSymbols;
+   }
+ };
+-
+ }
+-
+ static ExplicitSymbolsDeleter Dummy;
+ 
+-
+ static llvm::sys::SmartMutex<true>& getMutex() {
+   static llvm::sys::SmartMutex<true> HandlesMutex;
+   return HandlesMutex;
+ }
+ 
+-void llvm::sys::DynamicLibrary::AddSymbol(StringRef symbolName,
+-                                          void *symbolValue) {
+-  SmartScopedLock<true> lock(getMutex());
+-  if (ExplicitSymbols == 0)
+-    ExplicitSymbols = new llvm::StringMap<void*>();
+-  (*ExplicitSymbols)[symbolName] = symbolValue;
+-}
+-
+ char llvm::sys::DynamicLibrary::Invalid = 0;
+ 
+-#ifdef LLVM_ON_WIN32
++static DenseMap<void *, unsigned> *OpenedHandles;
++static const unsigned PermanentRefCount = (unsigned)-1;
+ 
+-#include "Windows/DynamicLibrary.inc"
++DynamicLibrary DynamicLibrary::getLibrary(const char *Filename, bool Permanent,
++                                          std::string *ErrMsg) {
++  SmartScopedLock<true> lock(getMutex());
+ 
+-#else
++  void *Handle = OpenLibraryImpl(Filename, ErrMsg);
++  if (Handle == 0) {
++    return DynamicLibrary();
++  }
++  if (OpenedHandles == 0)
++    OpenedHandles = new DenseMap<void *, unsigned>();
+ 
+-#if HAVE_DLFCN_H
+-#include <dlfcn.h>
+-using namespace llvm;
+-using namespace llvm::sys;
++  // If we've already loaded this library, dlclose() the handle in order to
++  // keep the internal refcount at +1.
++  unsigned &RefCount = (*OpenedHandles)[Handle];
++  if (RefCount > 0)
++    CloseLibraryImpl(Handle, 0);
+ 
+-//===----------------------------------------------------------------------===//
+-//=== WARNING: Implementation here must contain only TRULY operating system
+-//===          independent code.
+-//===----------------------------------------------------------------------===//
++  if (Permanent)
++    RefCount = PermanentRefCount;
++  else
++    ++RefCount;
+ 
+-static DenseSet<void *> *OpenedHandles = 0;
++  return DynamicLibrary(Handle);
++}  
+ 
+-DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
+-                                                   std::string *errMsg) {
+-  SmartScopedLock<true> lock(getMutex());
++static bool UnloadHandle(void *DlHandle, std::string *ErrMsg) {
++  // Caller must lock!
+ 
+-  void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL);
+-  if (handle == 0) {
+-    if (errMsg) *errMsg = dlerror();
+-    return DynamicLibrary();
++  if (!DlHandle) {
++    if (ErrMsg)
++      *ErrMsg = "Cannot unload invalid DynamicLibrary.";
++    return false;
+   }
+ 
+-#ifdef __CYGWIN__
+-  // Cygwin searches symbols only in the main
+-  // with the handle of dlopen(NULL, RTLD_GLOBAL).
+-  if (filename == NULL)
+-    handle = RTLD_DEFAULT;
+-#endif
++  assert(OpenedHandles && "No dynamic libraries have been loaded.");
+ 
+-  if (OpenedHandles == 0)
+-    OpenedHandles = new DenseSet<void *>();
++  SmartScopedLock<true> Lock(getMutex());
+ 
+-  // If we've already loaded this library, dlclose() the handle in order to
+-  // keep the internal refcount at +1.
+-  if (!OpenedHandles->insert(handle).second)
+-    dlclose(handle);
++  DenseMap<void *, unsigned>::iterator I = OpenedHandles->find(DlHandle);
++  if (I == OpenedHandles->end()) {
++    if (ErrMsg)
++      *ErrMsg = "DynamicLibrary has already been closed";
++    return false;
++  }
++  if (I->second == PermanentRefCount) {
++    if (ErrMsg)
++      *ErrMsg = std::string("Cannot close permanent library.");
++    return false;
++  }
++  --I->second;
++  if (I->second == 0)
++    return CloseLibraryImpl(DlHandle, ErrMsg);
+ 
+-  return DynamicLibrary(handle);
++  // Ref count not yet 0, but no error.
++  return true;
+ }
+ 
+-void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
+-  if (!isValid())
+-    return NULL;
+-  return dlsym(Data, symbolName);
+-}
++bool DynamicLibrary::Unload(const char *Filename, std::string *ErrMsg) {
++  if (!OpenedHandles) {
++    if (ErrMsg)
++      *ErrMsg = "No dynamic libraries have been loaded.";
++    return false;
++  }
+ 
+-#else
++  SmartScopedLock<true> Lock(getMutex());
++  void *DlHandle = OpenLibraryImpl(Filename, ErrMsg);
++  if (!DlHandle) {
++    if (ErrMsg) {
++      // The error message from OpenLibraryImpl() will complain about
++      // not being able to open the library which is confusing for a
++      // call to Unload().
++      *ErrMsg = std::string("Cannot find dynamic library ") + Filename;
++    }
++    return false;
++  }
+ 
+-using namespace llvm;
+-using namespace llvm::sys;
++  return UnloadHandle(DlHandle, ErrMsg);
++}
+ 
+-DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
+-                                                   std::string *errMsg) {
+-  if (errMsg) *errMsg = "dlopen() not supported on this platform";
+-  return DynamicLibrary();
++bool DynamicLibrary::Unload(std::string *ErrMsg) {
++  return UnloadHandle(Data, ErrMsg);
+ }
+ 
+-void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
+-  return NULL;
++void llvm::sys::DynamicLibrary::AddSymbol(StringRef SymbolName,
++                                          void *SymbolValue) {
++  SmartScopedLock<true> lock(getMutex());
++  if (ExplicitSymbols == 0)
++    ExplicitSymbols = new StringMap<void *>();
++  (*ExplicitSymbols)[SymbolName] = SymbolValue;
+ }
+ 
+-#endif
++void *DynamicLibrary::getAddressOfSymbol(const char *SymbolName) {
++  return GetAddressOfSymbolImpl(Data, SymbolName, false /*Global*/);
++}
+ 
+-namespace llvm {
+-void *SearchForAddressOfSpecialSymbol(const char* symbolName);
++void *DynamicLibrary::SearchForLibrarySymbol(const char *SymbolName) {
++  if (OpenedHandles) {
++    for (DenseMap<void *, unsigned>::iterator I = OpenedHandles->begin(),
++         E = OpenedHandles->end(); I != E; ++I) {
++      void *ptr = GetAddressOfSymbolImpl(I->first, SymbolName, true /*Global*/);
++      if (ptr) {
++        return ptr;
++      }
++    }
++  }
++  return NULL;
+ }
+ 
+-void* DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) {
++void *DynamicLibrary::SearchForAddressOfSymbol(const char *SymbolName) {
+   SmartScopedLock<true> Lock(getMutex());
+ 
+   // First check symbols added via AddSymbol().
+   if (ExplicitSymbols) {
+-    StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName);
++    StringMap<void *>::iterator i = ExplicitSymbols->find(SymbolName);
+ 
+     if (i != ExplicitSymbols->end())
+       return i->second;
+   }
+ 
+-#if HAVE_DLFCN_H
+   // Now search the libraries.
+-  if (OpenedHandles) {
+-    for (DenseSet<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;
+-      }
+-    }
++  if (void *ptr = SearchForLibrarySymbol(SymbolName))
++    return ptr;
++
++  // Finally check platform specific symbols.
++  if (SpecialSymbols) {
++    StringMap<void *>::iterator i = SpecialSymbols->Map.find(SymbolName);
++
++    if (i != SpecialSymbols->Map.end())
++      return i->second;
+   }
+-#endif
+ 
+-  if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName))
+-    return Result;
++  return 0;
++}
+ 
+-// 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__) and !defined(__ANDROID__)
+-  {
+-    EXPLICIT_SYMBOL(stderr);
+-    EXPLICIT_SYMBOL(stdout);
+-    EXPLICIT_SYMBOL(stdin);
+-  }
++#ifdef LLVM_ON_WIN32
++
++#include "Windows/DynamicLibrary.inc"
++
+ #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;
++#if HAVE_DLFCN_H
++#include "Unix/DynamicLibrary.inc"
++#else
++
++void *OpenLibraryImpl(const char *, std::string *errMsg) {
++  if (errMsg) *errMsg = "dlopen() not supported on this platform";
++  return NULL;
+ }
++bool CloseLibraryImpl(void *, std::string *ErrMsg) {
++  if (errMsg) *errMsg = "dlclose() not supported on this platform";
++  retun false;
++}
++void *GetAddressOfSymbolImpl(void *, const char *, bool) {
++  return NULL;
++}
++void PopulateSpecialSymbolsImpl(StringMap<void *>&) {
++}
+ 
++#endif
++
++
+ #endif // LLVM_ON_WIN32
 Index: lib/Support/Windows/DynamicLibrary.inc
 ===================================================================
 --- lib/Support/Windows/DynamicLibrary.inc	(revision 167609)

-
-
-}
Index: lib/Support/SearchForAddressOfSpecialSymbol.cpp
===================================================================
--- lib/Support/SearchForAddressOfSpecialSymbol.cpp	(revision 167609)

+    return &OpenedHandles;
   }
   
-  HMODULE a_handle = LoadLibrary(filename);
+  HMODULE a_handle = LoadLibrary(Filename);
 
   if (a_handle == 0) {
-    MakeErrMsg(errMsg, std::string(filename) + ": Can't open : ");
-    return DynamicLibrary();
+    MakeErrMsg(ErrMsg, std::string(Filename) + ": Can't open : ");
+    return NULL;
   }
 
