DynamicLibrary.inc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. #if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
  14. #include <dlfcn.h>
  15. DynamicLibrary::HandleSet::~HandleSet() {
  16. for (void *Handle : Handles)
  17. ::dlclose(Handle);
  18. if (Process)
  19. ::dlclose(Process);
  20. }
  21. void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
  22. void *Handle = ::dlopen(File, RTLD_LAZY|RTLD_GLOBAL);
  23. if (!Handle) {
  24. if (Err) *Err = ::dlerror();
  25. return &DynamicLibrary::Invalid;
  26. }
  27. #ifdef __CYGWIN__
  28. // Cygwin searches symbols only in the main
  29. // with the handle of dlopen(NULL, RTLD_GLOBAL).
  30. if (!Filename)
  31. Handle = RTLD_DEFAULT;
  32. #endif
  33. return Handle;
  34. }
  35. void DynamicLibrary::HandleSet::DLClose(void *Handle) {
  36. ::dlclose(Handle);
  37. }
  38. void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
  39. return ::dlsym(Handle, Symbol);
  40. }
  41. #else // !HAVE_DLOPEN
  42. DynamicLibrary::HandleSet::~HandleSet() {}
  43. void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
  44. if (Err) *Err = "dlopen() not supported on this platform";
  45. return &Invalid;
  46. }
  47. void DynamicLibrary::HandleSet::DLClose(void *Handle) {
  48. }
  49. void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
  50. return nullptr;
  51. }
  52. #endif
  53. // Must declare the symbols in the global namespace.
  54. static void *DoSearch(const char* SymbolName) {
  55. #define EXPLICIT_SYMBOL(SYM) \
  56. extern void *SYM; if (!strcmp(SymbolName, #SYM)) return &SYM
  57. // If this is darwin, it has some funky issues, try to solve them here. Some
  58. // important symbols are marked 'private external' which doesn't allow
  59. // SearchForAddressOfSymbol to find them. As such, we special case them here,
  60. // there is only a small handful of them.
  61. #ifdef __APPLE__
  62. {
  63. // __eprintf is sometimes used for assert() handling on x86.
  64. //
  65. // FIXME: Currently disabled when using Clang, as we don't always have our
  66. // runtime support libraries available.
  67. #ifndef __clang__
  68. #ifdef __i386__
  69. EXPLICIT_SYMBOL(__eprintf);
  70. #endif
  71. #endif
  72. }
  73. #endif
  74. #ifdef __CYGWIN__
  75. {
  76. EXPLICIT_SYMBOL(_alloca);
  77. EXPLICIT_SYMBOL(__main);
  78. }
  79. #endif
  80. #undef EXPLICIT_SYMBOL
  81. // This macro returns the address of a well-known, explicit symbol
  82. #define EXPLICIT_SYMBOL(SYM) \
  83. if (!strcmp(SymbolName, #SYM)) return &SYM
  84. // On linux we have a weird situation. The stderr/out/in symbols are both
  85. // macros and global variables because of standards requirements. So, we
  86. // boldly use the EXPLICIT_SYMBOL macro without checking for a #define first.
  87. #if defined(__linux__) and !defined(__ANDROID__)
  88. {
  89. EXPLICIT_SYMBOL(stderr);
  90. EXPLICIT_SYMBOL(stdout);
  91. EXPLICIT_SYMBOL(stdin);
  92. }
  93. #else
  94. // For everything else, we want to check to make sure the symbol isn't defined
  95. // as a macro before using EXPLICIT_SYMBOL.
  96. {
  97. #ifndef stdin
  98. EXPLICIT_SYMBOL(stdin);
  99. #endif
  100. #ifndef stdout
  101. EXPLICIT_SYMBOL(stdout);
  102. #endif
  103. #ifndef stderr
  104. EXPLICIT_SYMBOL(stderr);
  105. #endif
  106. }
  107. #endif
  108. #undef EXPLICIT_SYMBOL
  109. return nullptr;
  110. }