27078836dd30a154d7eafd9c81b0ff921b600957
[oota-llvm.git] / lib / System / Win32 / DynamicLibrary.cpp
1 //===- Win32/DynamicLibrary.cpp - Win32 DL Implementation -------*- C++ -*-===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Jeff Cohen and is distributed under the 
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file provides the Win32 specific implementation of  DynamicLibrary.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "Win32.h"
15 #include <dbghelp.h>
16
17 #pragma comment(lib, "dbghelp.lib")
18
19 namespace llvm {
20 using namespace sys;
21
22 //===----------------------------------------------------------------------===//
23 //=== WARNING: Implementation here must contain only Win32 specific code 
24 //===          and must not be UNIX code.
25 //===----------------------------------------------------------------------===//
26
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
38 DynamicLibrary::DynamicLibrary() : handle(0) {
39   handle = GetModuleHandle(NULL);
40   OpenedHandles.push_back((HMODULE)handle);
41 }
42
43 DynamicLibrary::DynamicLibrary(const char*filename) : handle(0) {
44   HMODULE a_handle = LoadLibrary(filename);
45
46   if (a_handle == 0)
47     ThrowError(std::string(filename) + ": Can't open : ");
48
49   handle = a_handle;
50   OpenedHandles.push_back(a_handle);
51 }
52
53 DynamicLibrary::~DynamicLibrary() {
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;
99 }
100
101 void *DynamicLibrary::GetAddressOfSymbol(const char *symbolName) {
102   assert(handle != 0 && "Invalid DynamicLibrary handle");
103   return GetProcAddress((HMODULE)handle, symbolName);
104 }
105
106 }
107
108 // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab