 ===================================================================
 --- 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());
+@@ -91,6 +91,13 @@ namespace sys {
+       return SearchForAddressOfSymbol(symbolName.c_str());
      }
  
 +    /// This function will search through all previously loaded dynamic

     // When no file is specified, enumerate all DLLs and EXEs in the process.
     if (OpenedHandles == 0)
-      OpenedHandles = new DenseSet<HMODULE>();
+      OpenedHandles = new DenseMap<void *, unsigned>();
 
     EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0);
     // Dummy library that represents "search all handles".

     /// This functions permanently adds the symbol \p symbolName with the
     /// value \p symbolValue.  These symbols are searched before any
     /// libraries.
Index: lib/Support/DynamicLibrary.cpp
===================================================================
--- lib/Support/DynamicLibrary.cpp	(revision 167609)
+++ lib/Support/DynamicLibrary.cpp	(working copy)
@@ -9,7 +9,7 @@
 //
 //  This header file implements the operating system DynamicLibrary concept.
 //
-// FIXME: This file leaks ExplicitSymbols and OpenedHandles!
+// FIXME: This file leaks OpenedHandles!
 //
 //===----------------------------------------------------------------------===//
 
@@ -21,11 +21,45 @@
 #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;
@@ -42,148 +76,98 @@ static llvm::sys::SmartMutex<true>& getMutex() {
   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 DenseSet<void *> *OpenedHandles;
 
-#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 DenseSet<void *> *OpenedHandles = 0;
-
-DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
-                                                   std::string *errMsg) {
+DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *Filename,
+                                                   std::string *ErrMsg) {
   SmartScopedLock<true> lock(getMutex());
 
-  void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL);
-  if (handle == 0) {
-    if (errMsg) *errMsg = dlerror();
+  void *Handle = OpenLibraryImpl(Filename, ErrMsg);
+  if (Handle == 0) {
     return DynamicLibrary();
   }
-
-#ifdef __CYGWIN__
-  // Cygwin searches symbols only in the main
-  // with the handle of dlopen(NULL, RTLD_GLOBAL).
-  if (filename == NULL)
-    handle = RTLD_DEFAULT;
-#endif
-
   if (OpenedHandles == 0)
     OpenedHandles = new DenseSet<void *>();
 
   // 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);
+  if (OpenedHandles->insert(Handle).second)
+    CloseLibraryImpl(Handle, 0);
 
-  return DynamicLibrary(handle);
-}
+  return DynamicLibrary(Handle);
+}  
 
-void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
-  if (!isValid())
-    return NULL;
-  return dlsym(Data, symbolName);
+void llvm::sys::DynamicLibrary::AddSymbol(StringRef SymbolName,
+                                          void *SymbolValue) {
+  SmartScopedLock<true> lock(getMutex());
+  if (ExplicitSymbols == 0)
+    ExplicitSymbols = new StringMap<void *>();
+  (*ExplicitSymbols)[SymbolName] = SymbolValue;
 }
 
-#else
-
-using namespace llvm;
-using namespace llvm::sys;
-
-DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
-                                                   std::string *errMsg) {
-  if (errMsg) *errMsg = "dlopen() not supported on this platform";
-  return DynamicLibrary();
+void *DynamicLibrary::getAddressOfSymbol(const char *SymbolName) {
+  return GetAddressOfSymbolImpl(Data, SymbolName, false /*Global*/);
 }
 
-void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
+void *DynamicLibrary::SearchForLibrarySymbol(const char *SymbolName) {
+  if (OpenedHandles) {
+    for (DenseSet<void *>::iterator I = OpenedHandles->begin(),
+         E = OpenedHandles->end(); I != E; ++I) {
+      void *ptr = GetAddressOfSymbolImpl(*I, SymbolName, true /*Global*/);
+      if (ptr) {
+        return ptr;
+      }
+    }
+  }
   return NULL;
 }
 
-#endif
-
-namespace llvm {
-void *SearchForAddressOfSpecialSymbol(const char* symbolName);
-}
-
-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;
-      }
-    }
-  }
-#endif
+  if (void *ptr = SearchForLibrarySymbol(SymbolName))
+    return ptr;
 
-  if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName))
-    return Result;
+  // Finally check platform specific symbols.
+  if (SpecialSymbols) {
+    StringMap<void *>::iterator i = SpecialSymbols->Map.find(SymbolName);
 
-// 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);
+    if (i != SpecialSymbols->Map.end())
+      return i->second;
   }
-#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;
 }
 
+#ifdef LLVM_ON_WIN32
+#include "Windows/DynamicLibrary.inc"
+#elif 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 // LLVM_ON_WIN32
Index: lib/Support/CMakeLists.txt
===================================================================
--- lib/Support/CMakeLists.txt	(revision 167609)
+++ lib/Support/CMakeLists.txt	(working copy)
@@ -80,6 +80,7 @@ add_llvm_library(LLVMSupport
   Threading.cpp
   TimeValue.cpp
   Valgrind.cpp
+  Unix/DynamicLibrary.inc
   Unix/Host.inc
   Unix/Memory.inc
   Unix/Mutex.inc
Index: lib/Support/Windows/DynamicLibrary.inc
===================================================================
--- lib/Support/Windows/DynamicLibrary.inc	(revision 167609)
+++ lib/Support/Windows/DynamicLibrary.inc	(working copy)
@@ -31,16 +31,8 @@
  #pragma comment(lib, "dbghelp.lib")
 #endif
 
