Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
3.3 KiB

  1. //========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Shared library loading and symbol lookup.
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "pch_tier0.h"
  8. #include "tier0/dynfunction.h"
  9. #if defined(WIN32)
  10. #include <windows.h>
  11. typedef HMODULE LibraryHandle;
  12. #define LoadLibraryHandle(libname) LoadLibrary(libname)
  13. #define CloseLibraryHandle(handle) FreeLibrary(handle)
  14. #define LookupInLibraryHandle(handle, fn) GetProcAddress(handle, fn)
  15. #elif defined(POSIX)
  16. #include <dlfcn.h>
  17. typedef void *LibraryHandle;
  18. #define LoadLibraryHandle(libname) dlopen(libname, RTLD_NOW)
  19. #define CloseLibraryHandle(handle) dlclose(handle)
  20. #define LookupInLibraryHandle(handle, fn) dlsym(handle, fn)
  21. #else
  22. #error Please define your platform.
  23. #endif
  24. #ifndef DEBUG
  25. static inline void dbgdynfn(const char *fmt, ...) {}
  26. #else
  27. #define dbgdynfn printf
  28. #endif
  29. // NOTE: This has to be the last file included!
  30. #include "tier0/memdbgon.h"
  31. class CSharedLibraryCache
  32. {
  33. public:
  34. static CSharedLibraryCache &GetCache()
  35. {
  36. static CSharedLibraryCache Singleton;
  37. return Singleton;
  38. }
  39. struct CSharedLibraryItem
  40. {
  41. CSharedLibraryItem(LibraryHandle handle, const char *name)
  42. {
  43. m_handle = handle;
  44. m_name = new char[strlen(name) + 1];
  45. m_next = NULL;
  46. strcpy(m_name, name);
  47. }
  48. ~CSharedLibraryItem()
  49. {
  50. dbgdynfn("CDynamicFunction: Closing library '%s' (%p)\n", m_name, (void *) m_handle);
  51. CloseLibraryHandle(m_handle);
  52. delete[] m_name;
  53. delete m_next;
  54. }
  55. char *m_name;
  56. CSharedLibraryItem *m_next;
  57. LibraryHandle m_handle;
  58. };
  59. CSharedLibraryCache() : m_pList(NULL) {}
  60. ~CSharedLibraryCache() { CloseAllLibraries(); }
  61. LibraryHandle GetHandle(const char *name)
  62. {
  63. CSharedLibraryItem *item = GetCacheItem(name);
  64. if (item == NULL)
  65. {
  66. LibraryHandle lib = LoadLibraryHandle(name);
  67. dbgdynfn("CDynamicFunction: Loading library '%s' (%p)\n", name, (void *) lib);
  68. if (lib == NULL)
  69. return NULL;
  70. item = new CSharedLibraryItem(lib, name);
  71. item->m_next = m_pList;
  72. m_pList = item;
  73. }
  74. return item->m_handle;
  75. }
  76. void CloseLibrary(const char *name)
  77. {
  78. CSharedLibraryItem *item = GetCacheItem(name);
  79. if (item)
  80. {
  81. assert(item == m_pList);
  82. m_pList = item->m_next;
  83. item->m_next = NULL;
  84. delete item;
  85. }
  86. }
  87. void CloseAllLibraries()
  88. {
  89. delete m_pList;
  90. }
  91. private:
  92. CSharedLibraryItem *GetCacheItem(const char *name)
  93. {
  94. CSharedLibraryItem *prev = NULL;
  95. CSharedLibraryItem *item = m_pList;
  96. while (item)
  97. {
  98. if (strcmp(item->m_name, name) == 0)
  99. {
  100. // move this item to the front of the list, since there will
  101. // probably be a big pile of these lookups in a row
  102. // and then none ever again.
  103. if (prev != NULL)
  104. {
  105. prev->m_next = item->m_next;
  106. item->m_next = m_pList;
  107. m_pList = item;
  108. }
  109. return item;
  110. }
  111. prev = item;
  112. item = item->m_next;
  113. }
  114. return NULL; // not found.
  115. }
  116. CSharedLibraryItem *m_pList;
  117. };
  118. void *VoidFnPtrLookup_Tier0(const char *libname, const char *fn, void *fallback)
  119. {
  120. LibraryHandle lib = CSharedLibraryCache::GetCache().GetHandle(libname);
  121. void *retval = NULL;
  122. if (lib != NULL)
  123. {
  124. retval = LookupInLibraryHandle(lib, fn);
  125. dbgdynfn("CDynamicFunction: Lookup of '%s' in '%s': %p\n", fn, libname, retval);
  126. }
  127. if (retval == NULL)
  128. retval = fallback;
  129. return retval;
  130. }