 ===================================================================
 --- lib/Support/Unix/DynamicLibrary.inc	(revision 0)
 +++ lib/Support/Unix/DynamicLibrary.inc	(revision 0)
-@@ -0,0 +1,105 @@
+@@ -0,0 +1,118 @@
 +//===--- Unix/DynamicLibrary.cpp - Unix DL Implementation -------*- C++ -*-===//
 +//
 +//                     The LLVM Compiler Infrastructure

 #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) EXPLICIT_SYMBOL(SYMTO)
 
 #include "explicit_symbols.inc"
@@ -113,51 +115,14 @@ extern "C" {
 #undef EXPLICIT_SYMBOL
 #undef EXPLICIT_SYMBOL2
 
-void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
-  SmartScopedLock<true> Lock(getMutex());
+void PopulateSpecialSymbolsImpl(StringMap<void *>& symMap) {
 
-  // First check symbols added via AddSymbol().
-  if (ExplicitSymbols) {
-    StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName);
+#define EXPLICIT_SYMBOL(SYM)                    \
+  symMap[#SYM] = &SYM;
+#define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) EXPLICIT_SYMBOL(SYMTO)
 
-    if (i != ExplicitSymbols->end())

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)
