DynamicLibrary.inc 3.5 KB

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