LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

DynamicLibrary.cpp

Go to the documentation of this file.
00001 //===-- DynamicLibrary.cpp - Runtime link/load libraries --------*- C++ -*-===//
00002 // 
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by Reid Spencer and is distributed under the 
00006 // University of Illinois Open Source License. See LICENSE.TXT for details.
00007 // 
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This header file implements the operating system DynamicLibrary concept.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "llvm/System/DynamicLibrary.h"
00015 #include "ltdl.h"
00016 #include <cassert>
00017 using namespace llvm;
00018 using namespace llvm::sys;
00019 
00020 //===----------------------------------------------------------------------===//
00021 //=== WARNING: Implementation here must contain only TRULY operating system
00022 //===          independent code. 
00023 //===----------------------------------------------------------------------===//
00024 
00025 static bool did_initialize_ltdl = false;
00026 
00027 static inline void check_ltdl_initialization() {
00028   if (!did_initialize_ltdl) {
00029     if (0 != lt_dlinit())
00030       throw std::string(lt_dlerror());
00031     did_initialize_ltdl = true;
00032   }
00033 }
00034 
00035 static std::vector<lt_dlhandle> OpenedHandles;
00036 
00037 DynamicLibrary::DynamicLibrary() : handle(0) {
00038   check_ltdl_initialization();
00039 
00040   lt_dlhandle a_handle = lt_dlopen(0);
00041 
00042   if (a_handle == 0)
00043     throw std::string("Can't open program as dynamic library");
00044   
00045   handle = a_handle;
00046   OpenedHandles.push_back(a_handle);
00047 }
00048 
00049 DynamicLibrary::DynamicLibrary(const char*filename) : handle(0) {
00050   check_ltdl_initialization();
00051 
00052   lt_dlhandle a_handle = lt_dlopen(filename);
00053 
00054   if (a_handle == 0)
00055     a_handle = lt_dlopenext(filename);
00056 
00057   if (a_handle == 0)
00058     throw std::string("Can't open :") + filename + ": " + lt_dlerror();
00059 
00060   handle = a_handle;
00061   OpenedHandles.push_back(a_handle);
00062 }
00063 
00064 DynamicLibrary::~DynamicLibrary() {
00065   lt_dlhandle a_handle = (lt_dlhandle) handle;
00066   if (a_handle) {
00067     lt_dlclose(a_handle);
00068 
00069     for (std::vector<lt_dlhandle>::iterator I = OpenedHandles.begin(),
00070          E = OpenedHandles.end(); I != E; ++I) {
00071       if (*I == a_handle) {
00072         // Note: don't use the swap/pop_back trick here. Order is important.
00073         OpenedHandles.erase(I);
00074       }
00075     }
00076   }
00077 }
00078 
00079 void DynamicLibrary::LoadLibraryPermanently(const char* filename) {
00080   check_ltdl_initialization();
00081   lt_dlhandle a_handle = lt_dlopen(filename);
00082 
00083   if (a_handle == 0)
00084     a_handle = lt_dlopenext(filename);
00085 
00086   if (a_handle == 0)
00087     throw std::string("Can't open :") + filename + ": " + lt_dlerror();
00088 
00089   lt_dlmakeresident(a_handle);
00090 
00091   OpenedHandles.push_back(a_handle);
00092 }
00093 
00094 void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
00095   check_ltdl_initialization();
00096   for (std::vector<lt_dlhandle>::iterator I = OpenedHandles.begin(),
00097        E = OpenedHandles.end(); I != E; ++I) {
00098     lt_ptr ptr = lt_dlsym(*I, symbolName);
00099     if (ptr)
00100       return ptr;
00101   }
00102 
00103   // If this is darwin, it has some funky issues, try to solve them here.  Some
00104   // important symbols are marked 'private external' which doesn't allow
00105   // SearchForAddressOfSymbol to find them.  As such, we special case them here,
00106   // there is only a small handful of them.
00107 #ifdef __APPLE__
00108   {
00109 #define EXPLICIT_SYMBOL(SYM) \
00110    extern void *SYM; if (!strcmp(symbolName, #SYM)) return &SYM
00111     EXPLICIT_SYMBOL(__ashldi3);
00112     EXPLICIT_SYMBOL(__ashrdi3);
00113     EXPLICIT_SYMBOL(__cmpdi2);
00114     EXPLICIT_SYMBOL(__divdi3);
00115     EXPLICIT_SYMBOL(__eprintf);
00116     EXPLICIT_SYMBOL(__fixdfdi);
00117     EXPLICIT_SYMBOL(__fixsfdi);
00118     EXPLICIT_SYMBOL(__fixunsdfdi);
00119     EXPLICIT_SYMBOL(__fixunssfdi);
00120     EXPLICIT_SYMBOL(__floatdidf);
00121     EXPLICIT_SYMBOL(__floatdisf);
00122     EXPLICIT_SYMBOL(__lshrdi3);
00123     EXPLICIT_SYMBOL(__moddi3);
00124     EXPLICIT_SYMBOL(__udivdi3);
00125     EXPLICIT_SYMBOL(__umoddi3);
00126 #undef EXPLICIT_SYMBOL
00127   }
00128 #endif
00129 
00130   return 0;
00131 }
00132 
00133 void *DynamicLibrary::GetAddressOfSymbol(const char *symbolName) {
00134   assert(handle != 0 && "Invalid DynamicLibrary handle");
00135   return lt_dlsym((lt_dlhandle) handle, symbolName);
00136 }
00137