 ===================================================================
 --- 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

+
+#undef EXPLICIT_SYMBOL
+}
Index: lib/Support/DynamicLibrary.cpp
===================================================================
--- lib/Support/DynamicLibrary.cpp	(revision 167609)
+++ lib/Support/DynamicLibrary.cpp	(working copy)
@@ -14,29 +14,52 @@
 //===----------------------------------------------------------------------===//
 
 #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 dymalic loader handle for the whole process.
+static void *OpenLibraryImpl(const char *filename, std::string *errMsg);
+// Close the shared library.
+static void  CloseLibraryImpl(void *dlHandle);
+// 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 ExplicitSymbolHolder {
+  ExplicitSymbolHolder() {
+    PopulateSpecialSymbolsImpl(Map);
+  }
 
+  // Symbol name/value pairs to be searched prior to any libraries.
+  StringMap<void *> Map;
+};
+}
+static ExplicitSymbolHolder* 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;
@@ -46,144 +69,85 @@ void llvm::sys::DynamicLibrary::AddSymbol(StringRe
                                           void *symbolValue) {
   SmartScopedLock<true> lock(getMutex());
   if (ExplicitSymbols == 0)
-    ExplicitSymbols = new llvm::StringMap<void*>();
-  (*ExplicitSymbols)[symbolName] = symbolValue;
+    ExplicitSymbols = new ExplicitSymbolHolder();
+  ExplicitSymbols->Map[symbolName] = symbolValue;
 }
 
 char llvm::sys::DynamicLibrary::Invalid = 0;
 
-#ifdef LLVM_ON_WIN32
+static DenseMap<void*, unsigned> *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) {
   SmartScopedLock<true> lock(getMutex());
 
-  void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL);
+  void *handle = OpenLibraryImpl(filename, errMsg);
   if (handle == 0) {
-    if (errMsg) *errMsg = dlerror();
     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 *>();
+    OpenedHandles = new DenseMap<void *, unsigned>();
 
   // 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)[handle] > 1)
+    CloseLibraryImpl(handle);
 
   return DynamicLibrary(handle);
-}
+}  
 
-void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
-  if (!isValid())
-    return NULL;
-  return dlsym(Data, symbolName);
-}
 
-#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) {
-  return NULL;
-}
-
-#endif
-
-namespace llvm {
-void *SearchForAddressOfSpecialSymbol(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->Map.find(symbolName);
 
-    if (i != ExplicitSymbols->end())
+    if (i != ExplicitSymbols->Map.end())
       return i->second;
   }
 
-#if HAVE_DLFCN_H
   // Now search the libraries.
   if (OpenedHandles) {
-    for (DenseSet<void *>::iterator I = OpenedHandles->begin(),
+    for (DenseMap<void *, unsigned>::iterator I = OpenedHandles->begin(),
          E = OpenedHandles->end(); I != E; ++I) {
       //lt_ptr ptr = lt_dlsym(*I, symbolName);
-      void *ptr = dlsym(*I, symbolName);
+      void *ptr = GetAddressOfSymbolImpl(I->first, symbolName, true /*Global*/);
       if (ptr) {
         return ptr;
       }
     }
   }
-#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
+#ifdef LLVM_ON_WIN32
 
-// 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);
-  }
+#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;
 }
+void CloseLibraryImpl(void *) {
+}
+void *GetAddressOfSymbolImpl(void *, const char *) {
+  return NULL;
+}
 
+#endif
+
+
 #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

-  // keep the internal refcount at +1.
-  if (!OpenedHandles->insert(a_handle).second)
-    FreeLibrary(a_handle);
+bool CloseLibraryImpl(void *DlHandle, std::string *ErrMsg) {
+  if (!FreeLibrary((HMODULE)DlHandle)) {
+    MakeErrMsg(ErrMsg, std::string(Filename) + ": Cannot close: ");
+    return false;
+  }
+  return true;
+}
 
-  return DynamicLibrary(a_handle);
+void *GetAddressOfSymbolImpl(void *DlHandle, const char *SymbolName,
+                             bool Global) {
+  if (DlHandle == &OpenedHandles) {
+    // Dummy library that represents "search all handles".
+    if (Global) {
+      // All libraries are already being searched, do not recurse.
+      return 0;
+    } else {
+      // Perform a global symbol search through all libraries.
+      DynamicLibrary::SearchForLibrarySymbol(SymbolName);
+    }
+  }
+  return (void *)(intptr_t) GetProcAddress((HMODULE)DlHandle, SymbolName);
 }
 
-// Stack probing routines are in the support library (e.g. libgcc), but we don't
