LCOV - code coverage report
Current view: top level - lib/Support/Unix - DynamicLibrary.inc (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 19 21 90.5 %
Date: 2018-10-20 13:21:21 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- Unix/DynamicLibrary.cpp - Unix DL Implementation ---------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file provides the UNIX specific implementation of DynamicLibrary.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
      15             : #include <dlfcn.h>
      16             : 
      17         128 : DynamicLibrary::HandleSet::~HandleSet() {
      18             :   // Close the libraries in reverse order.
      19         216 :   for (void *Handle : llvm::reverse(Handles))
      20          88 :     ::dlclose(Handle);
      21         128 :   if (Process)
      22          42 :     ::dlclose(Process);
      23             : 
      24             :   // llvm_shutdown called, Return to default
      25         128 :   DynamicLibrary::SearchOrder = DynamicLibrary::SO_Linker;
      26         128 : }
      27             : 
      28         472 : void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
      29         472 :   void *Handle = ::dlopen(File, RTLD_LAZY|RTLD_GLOBAL);
      30         472 :   if (!Handle) {
      31           0 :     if (Err) *Err = ::dlerror();
      32           0 :     return &DynamicLibrary::Invalid;
      33             :   }
      34             : 
      35             : #ifdef __CYGWIN__
      36             :   // Cygwin searches symbols only in the main
      37             :   // with the handle of dlopen(NULL, RTLD_GLOBAL).
      38             :   if (!File)
      39             :     Handle = RTLD_DEFAULT;
      40             : #endif
      41             : 
      42             :   return Handle;
      43             : }
      44             : 
      45         123 : void DynamicLibrary::HandleSet::DLClose(void *Handle) {
      46         123 :   ::dlclose(Handle);
      47         123 : }
      48             : 
      49         293 : void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
      50         293 :   return ::dlsym(Handle, Symbol);
      51             : }
      52             : 
      53             : #else // !HAVE_DLOPEN
      54             : 
      55             : DynamicLibrary::HandleSet::~HandleSet() {}
      56             : 
      57             : void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
      58             :   if (Err) *Err = "dlopen() not supported on this platform";
      59             :   return &Invalid;
      60             : }
      61             : 
      62             : void DynamicLibrary::HandleSet::DLClose(void *Handle) {
      63             : }
      64             : 
      65             : void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
      66             :   return nullptr;
      67             : }
      68             : 
      69             : #endif
      70             : 
      71             : // Must declare the symbols in the global namespace.
      72          37 : static void *DoSearch(const char* SymbolName) {
      73             : #define EXPLICIT_SYMBOL(SYM) \
      74             :    extern void *SYM; if (!strcmp(SymbolName, #SYM)) return (void*)&SYM
      75             : 
      76             :   // If this is darwin, it has some funky issues, try to solve them here.  Some
      77             :   // important symbols are marked 'private external' which doesn't allow
      78             :   // SearchForAddressOfSymbol to find them.  As such, we special case them here,
      79             :   // there is only a small handful of them.
      80             : 
      81             : #ifdef __APPLE__
      82             :   {
      83             :     // __eprintf is sometimes used for assert() handling on x86.
      84             :     //
      85             :     // FIXME: Currently disabled when using Clang, as we don't always have our
      86             :     // runtime support libraries available.
      87             : #ifndef __clang__
      88             : #ifdef __i386__
      89             :     EXPLICIT_SYMBOL(__eprintf);
      90             : #endif
      91             : #endif
      92             :   }
      93             : #endif
      94             : 
      95             : #ifdef __CYGWIN__
      96             :   {
      97             :     EXPLICIT_SYMBOL(_alloca);
      98             :     EXPLICIT_SYMBOL(__main);
      99             :   }
     100             : #endif
     101             : 
     102             : #undef EXPLICIT_SYMBOL
     103             : 
     104             : // This macro returns the address of a well-known, explicit symbol
     105             : #define EXPLICIT_SYMBOL(SYM) \
     106             :    if (!strcmp(SymbolName, #SYM)) return &SYM
     107             : 
     108             : // Under glibc we have a weird situation. The stderr/out/in symbols are both
     109             : // macros and global variables because of standards requirements. So, we
     110             : // boldly use the EXPLICIT_SYMBOL macro without checking for a #define first.
     111             : #if defined(__GLIBC__)
     112             :   {
     113          37 :     EXPLICIT_SYMBOL(stderr);
     114          37 :     EXPLICIT_SYMBOL(stdout);
     115          37 :     EXPLICIT_SYMBOL(stdin);
     116             :   }
     117             : #else
     118             :   // For everything else, we want to check to make sure the symbol isn't defined
     119             :   // as a macro before using EXPLICIT_SYMBOL.
     120             :   {
     121             : #ifndef stdin
     122             :     EXPLICIT_SYMBOL(stdin);
     123             : #endif
     124             : #ifndef stdout
     125             :     EXPLICIT_SYMBOL(stdout);
     126             : #endif
     127             : #ifndef stderr
     128             :     EXPLICIT_SYMBOL(stderr);
     129             : #endif
     130             :   }
     131             : #endif
     132             : #undef EXPLICIT_SYMBOL
     133             : 
     134             :   return nullptr;
     135             : }

Generated by: LCOV version 1.13