-}
-
-void DynamicLibrary::LoadLibraryPermanently(const char* filename) {
- check_ltdl_initialization();
- lt_dlhandle a_handle = lt_dlopen(filename);
-
- if (a_handle == 0)
- a_handle = lt_dlopenext(filename);
-
- if (a_handle == 0)
- throw std::string("Can't open :") + filename + ": " + lt_dlerror();
-
- lt_dlmakeresident(a_handle);
-
- OpenedHandles.push_back(a_handle);
-}
-
-void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
- check_ltdl_initialization();
- for (std::vector<lt_dlhandle>::iterator I = OpenedHandles.begin(),
- E = OpenedHandles.end(); I != E; ++I) {
- lt_ptr ptr = lt_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);