Fix Windows build
[dyninst.git] / common / src / addrtranslate-win.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #include <stdio.h>
33 #define WIN32_LEAN_AND_MEAN
34 #include <windows.h>
35
36 #include <vector>
37 #include <string>
38
39 #include "common/h/addrtranslate.h"
40 #include "Psapi.h"
41
42 using namespace std;
43
44 namespace Dyninst {
45
46 class AddressTranslateWin : public AddressTranslate
47 {
48 private:
49    bool no_proc;
50 public:
51    virtual bool init();
52    virtual bool refresh();
53    AddressTranslateWin(PID pid, PROC_HANDLE phandle);
54    void setNoProc(bool b);
55    virtual Address getLibraryTrapAddrSysV();
56
57 };
58
59 }
60
61 using namespace Dyninst;
62
63 void AddressTranslateWin::setNoProc(bool b)
64 {
65    no_proc = b;
66 }
67
68 AddressTranslate *AddressTranslate::createAddressTranslator(PID pid_, ProcessReader *, SymbolReaderFactory *, PROC_HANDLE phandle_, std::string)
69 {
70         AddressTranslateWin *new_translate = new AddressTranslateWin(pid_, phandle_);
71         if (!new_translate)
72                 return NULL;
73         if (new_translate->creation_error)
74                 return NULL;
75         return new_translate;
76 }
77
78 AddressTranslate *AddressTranslate::createAddressTranslator(ProcessReader *, SymbolReaderFactory *, std::string)
79 {
80         //return createAddressTranslator(GetCurrentProcess(), NULL);
81         return createAddressTranslator(GetCurrentProcessId(), NULL, NULL, GetCurrentProcess());
82 }
83
84 bool AddressTranslateWin::init()
85 {
86         bool result = refresh();
87         if (!result)
88                 creation_error = true;
89         return true;
90 }
91
92 void printSysError(unsigned errNo) {
93     char buf[1000];
94     DWORD result = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errNo, 
95                   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
96                   buf, 1000, NULL);
97     if (!result) {
98         fprintf(stderr, "Couldn't print error message\n");
99         printSysError(GetLastError());
100     }
101     fprintf(stderr, "*** System error [%d]: %s\n", errNo, buf);
102     fflush(stderr);
103 }
104
105 bool AddressTranslateWin::refresh()
106 {
107         HANDLE currentProcess = phandle;
108         int result;
109
110    if (no_proc)
111       return true;
112
113    for (unsigned i=0; i<libs.size(); i++)
114       if (libs[i]) delete libs[i];
115         libs.clear();
116    
117         //Calculate the number of modules
118         DWORD num_modules_needed, total_space;
119    result = EnumProcessModules(currentProcess,
120                                NULL,
121                                0,
122                                &total_space);
123         if (!result) {
124                 return false;
125         }
126         num_modules_needed = total_space / sizeof(HMODULE);
127     
128         //Get modules
129         HMODULE* loadedModules = new HMODULE[num_modules_needed];
130    result = EnumProcessModules(currentProcess,
131                                loadedModules,
132                                sizeof(HMODULE) * num_modules_needed,
133                                &total_space);
134         if (!result) {
135       printSysError(GetLastError());
136                 return false;
137         }
138    
139         //Add modules to libs
140         for (HMODULE *i = loadedModules; i < loadedModules + num_modules_needed; i++)
141         {
142                 MODULEINFO info;
143                 TCHAR filename[MAX_PATH];
144                 
145                 result = GetModuleInformation(currentProcess, *i, &info, sizeof(info));
146                 if (!result)
147                         continue;
148       result = GetModuleFileNameEx(currentProcess, *i, filename, MAX_PATH);
149       if (!result)
150          continue;
151       
152       LoadedLib *ll = new LoadedLib(std::string(filename), (Address) info.lpBaseOfDll);
153       ll->add_mapped_region((Address) info.lpBaseOfDll, info.SizeOfImage);
154       libs.push_back(ll);
155         }
156         
157         delete [] loadedModules;
158         return true;
159 }
160
161 vector< pair<Address, unsigned long> > *LoadedLib::getMappedRegions()
162 {
163    return &mapped_regions;
164 }
165
166 AddressTranslateWin::AddressTranslateWin(PID pid, PROC_HANDLE phandle_) :
167         AddressTranslate(pid, phandle_),
168    no_proc(false)
169 {
170         init();
171 }
172
173 Address AddressTranslateWin::getLibraryTrapAddrSysV()
174 {
175    return 0x0;
176 }