Reid Spencer | ebf8d0e | 2004-12-24 06:03:31 +0000 | [diff] [blame] | 1 | //===- Win32/DynamicLibrary.cpp - Win32 DL Implementation -------*- C++ -*-===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
Jeff Cohen | 1a46635 | 2004-12-24 07:57:09 +0000 | [diff] [blame^] | 5 | // This file was developed by Jeff Cohen and is distributed under the |
Reid Spencer | ebf8d0e | 2004-12-24 06:03:31 +0000 | [diff] [blame] | 6 | // University of Illinois Open Source License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
Jeff Cohen | 1a46635 | 2004-12-24 07:57:09 +0000 | [diff] [blame^] | 10 | // This file provides the Win32 specific implementation of DynamicLibrary. |
Reid Spencer | ebf8d0e | 2004-12-24 06:03:31 +0000 | [diff] [blame] | 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #include "Win32.h" |
Jeff Cohen | 1a46635 | 2004-12-24 07:57:09 +0000 | [diff] [blame^] | 15 | #include <dbghelp.h> |
| 16 | |
| 17 | #pragma comment(lib, "dbghelp.lib") |
Reid Spencer | ebf8d0e | 2004-12-24 06:03:31 +0000 | [diff] [blame] | 18 | |
| 19 | namespace llvm { |
| 20 | using namespace sys; |
| 21 | |
| 22 | //===----------------------------------------------------------------------===// |
| 23 | //=== WARNING: Implementation here must contain only Win32 specific code |
Jeff Cohen | 1a46635 | 2004-12-24 07:57:09 +0000 | [diff] [blame^] | 24 | //=== and must not be UNIX code. |
Reid Spencer | ebf8d0e | 2004-12-24 06:03:31 +0000 | [diff] [blame] | 25 | //===----------------------------------------------------------------------===// |
| 26 | |
Jeff Cohen | 1a46635 | 2004-12-24 07:57:09 +0000 | [diff] [blame^] | 27 | static std::vector<HMODULE> OpenedHandles; |
| 28 | |
| 29 | BOOL CALLBACK ELM_Callback(PSTR ModuleName, |
| 30 | ULONG ModuleBase, |
| 31 | ULONG ModuleSize, |
| 32 | PVOID UserContext) |
| 33 | { |
| 34 | OpenedHandles.push_back((HMODULE)ModuleBase); |
| 35 | return TRUE; |
| 36 | } |
| 37 | |
Reid Spencer | ebf8d0e | 2004-12-24 06:03:31 +0000 | [diff] [blame] | 38 | DynamicLibrary::DynamicLibrary() : handle(0) { |
Jeff Cohen | 1a46635 | 2004-12-24 07:57:09 +0000 | [diff] [blame^] | 39 | handle = GetModuleHandle(NULL); |
| 40 | OpenedHandles.push_back((HMODULE)handle); |
Reid Spencer | ebf8d0e | 2004-12-24 06:03:31 +0000 | [diff] [blame] | 41 | } |
| 42 | |
| 43 | DynamicLibrary::DynamicLibrary(const char*filename) : handle(0) { |
Jeff Cohen | 1a46635 | 2004-12-24 07:57:09 +0000 | [diff] [blame^] | 44 | HMODULE a_handle = LoadLibrary(filename); |
Reid Spencer | ebf8d0e | 2004-12-24 06:03:31 +0000 | [diff] [blame] | 45 | |
Jeff Cohen | 1a46635 | 2004-12-24 07:57:09 +0000 | [diff] [blame^] | 46 | if (a_handle == 0) |
| 47 | ThrowError(std::string(filename) + ": Can't open : "); |
| 48 | |
| 49 | handle = a_handle; |
| 50 | OpenedHandles.push_back(a_handle); |
Reid Spencer | ebf8d0e | 2004-12-24 06:03:31 +0000 | [diff] [blame] | 51 | } |
| 52 | |
| 53 | DynamicLibrary::~DynamicLibrary() { |
Jeff Cohen | 1a46635 | 2004-12-24 07:57:09 +0000 | [diff] [blame^] | 54 | if (handle == 0) |
| 55 | return; |
| 56 | |
| 57 | // GetModuleHandle() does not increment the ref count, so we must not free |
| 58 | // the handle to the executable. |
| 59 | if (handle != GetModuleHandle(NULL)) |
| 60 | FreeLibrary((HMODULE)handle); |
| 61 | handle = 0; |
| 62 | |
| 63 | for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(), |
| 64 | E = OpenedHandles.end(); I != E; ++I) { |
| 65 | if (*I == handle) { |
| 66 | // Note: don't use the swap/pop_back trick here. Order is important. |
| 67 | OpenedHandles.erase(I); |
| 68 | } |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | void DynamicLibrary::LoadLibraryPermanently(const char* filename) { |
| 73 | if (filename) { |
| 74 | HMODULE a_handle = LoadLibrary(filename); |
| 75 | |
| 76 | if (a_handle == 0) |
| 77 | ThrowError(std::string(filename) + ": Can't open : "); |
| 78 | |
| 79 | OpenedHandles.push_back(a_handle); |
| 80 | } else { |
| 81 | // When no file is specified, enumerate all DLLs and EXEs in the |
| 82 | // process. |
| 83 | EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0); |
| 84 | } |
| 85 | |
| 86 | // Because we don't remember the handles, we will never free them; hence, |
| 87 | // it is loaded permanently. |
| 88 | } |
| 89 | |
| 90 | void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { |
| 91 | for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(), |
| 92 | E = OpenedHandles.end(); I != E; ++I) { |
| 93 | FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName); |
| 94 | if (ptr) |
| 95 | return ptr; |
| 96 | } |
| 97 | |
| 98 | return 0; |
Reid Spencer | ebf8d0e | 2004-12-24 06:03:31 +0000 | [diff] [blame] | 99 | } |
| 100 | |
| 101 | void *DynamicLibrary::GetAddressOfSymbol(const char *symbolName) { |
Jeff Cohen | 1a46635 | 2004-12-24 07:57:09 +0000 | [diff] [blame^] | 102 | assert(handle != 0 && "Invalid DynamicLibrary handle"); |
| 103 | return GetProcAddress((HMODULE)handle, symbolName); |
Reid Spencer | ebf8d0e | 2004-12-24 06:03:31 +0000 | [diff] [blame] | 104 | } |
| 105 | |
| 106 | } |
| 107 | |
| 108 | // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab |