windows build fix,
[dyninst.git] / symtabAPI / src / Module.C
1 /*
2  * Copyright (c) 1996-2007 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 * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
29  */
30
31 #include "Module.h"
32 #include "Symtab.h"
33 #include "Symtab.h"
34 #include "Collections.h"
35
36 #include "common/h/pathName.h"
37
38 using namespace Dyninst;
39 using namespace Dyninst::SymtabAPI;
40 using namespace std;
41
42 static SymtabError serr;
43
44 bool Module::findSymbolByType(std::vector<Symbol *> &found, 
45       const std::string name,
46       Symbol::SymbolType sType, 
47       bool isMangled,
48       bool isRegex, 
49       bool checkCase)
50 {
51    unsigned orig_size = found.size();
52    std::vector<Symbol *> obj_syms;
53
54    if (!exec()->findSymbolByType(obj_syms, name, sType, isMangled, isRegex, checkCase))
55    {
56       //fprintf(stderr, "%s[%d]:  no symbols matching %s found\n", FILE__, __LINE__, name.c_str());
57       return false;
58    }
59
60    for (unsigned i = 0; i < obj_syms.size(); i++)  
61    {
62       if (obj_syms[i]->getModule() == this)
63          found.push_back(obj_syms[i]);
64 #if 0
65       else 
66       {
67          if (obj_syms[i]->getName() == name) {
68             fprintf(stderr, "%s[%d]:  found symbol %s in different module %s not %s\n", 
69                   FILE__, __LINE__, name.c_str(), 
70                   obj_syms[i]->getModule()->fileName().c_str(), 
71                   this->fileName().c_str());
72          }
73       }
74 #endif
75    }
76
77    if (found.size() > orig_size) 
78       return true;
79
80    return false;        
81 }
82
83 DLLEXPORT const std::string &Module::fileName() const
84 {
85    return fileName_;
86 }
87
88 DLLEXPORT const std::string &Module::fullName() const
89 {
90    return fullName_;
91 }
92
93 DLLEXPORT Symtab *Module::exec() const
94 {
95    return exec_;
96 }
97
98 DLLEXPORT supportedLanguages Module::language() const
99 {
100    return language_;
101 }
102
103 DLLEXPORT  bool Module::hasLineInformation()
104 {
105    Annotatable<LineInformation *, module_line_info_a,  true> &liA = *this;
106    return ( 0 != liA.size());
107 }
108
109 DLLEXPORT LineInformation *Module::getLineInformation()
110 {
111    if (!exec_->isLineInfoValid_)
112       exec_->parseLineInformation();
113
114    Annotatable<LineInformation *, module_line_info_a,  true> &mt = *this;
115
116    if (exec_->isLineInfoValid_) {
117       if (!mt.size()) {
118           // There is no line info valid for this module
119          return NULL;
120       }
121       if (mt.size() > 1) {
122         // fprintf(stderr, "%s[%d]:  weird, multiple line info for %s: FIXME\n", 
123         //       FILE__, __LINE__, fileName_.c_str());
124       }
125       if (!mt[0]) {
126          fprintf(stderr, "%s[%d]:  FIXME:  Line info annotation is NULL!\n", FILE__, __LINE__);
127       }
128       return mt[0];
129    }
130
131    fprintf(stderr, "%s[%d]:  FIXME:  line info not valid after parse\n",
132          FILE__, __LINE__);
133
134    return NULL;
135 }
136
137 DLLEXPORT bool Module::getAddressRanges(std::vector<pair<Offset, Offset> >&ranges,
138       std::string lineSource, unsigned int lineNo)
139 {
140    unsigned int originalSize = ranges.size();
141
142    LineInformation *lineInformation = getLineInformation();
143    if (lineInformation)
144       lineInformation->getAddressRanges( lineSource.c_str(), lineNo, ranges );
145
146    if ( ranges.size() != originalSize )
147       return true;
148
149    return false;
150 }
151
152 DLLEXPORT bool Module::getSourceLines(std::vector<LineNoTuple> &lines, Offset addressInRange)
153 {
154    unsigned int originalSize = lines.size();
155
156    LineInformation *lineInformation = getLineInformation();
157    if (lineInformation)
158       lineInformation->getSourceLines( addressInRange, lines );
159
160    if ( lines.size() != originalSize )
161       return true;
162
163    return false;
164 }
165
166 DLLEXPORT vector<Type *> *Module::getAllTypes()
167 {
168    Annotatable<typeCollection *, module_type_info_a,  true> &mtA = *this;
169    if (!mtA.size()) return NULL;
170
171    typeCollection *mt = mtA[0];
172    if (!mt) {
173       fprintf(stderr, "%s[%d]:  FIXME:  NULL type collection\n", FILE__, __LINE__);
174       return NULL;
175    }
176
177    return mt->getAllTypes();
178 }
179
180 DLLEXPORT vector<pair<string, Type *> > *Module::getAllGlobalVars()
181 {
182    Annotatable<typeCollection *, module_type_info_a,  true> &mtA = *this;
183    if (!mtA.size()) return NULL;
184
185    typeCollection *mt = mtA[0];
186    if (!mt) {
187       fprintf(stderr, "%s[%d]:  FIXME:  NULL type collection\n", FILE__, __LINE__);
188       return NULL;
189    }
190
191    return mt->getAllGlobalVariables();
192 }
193
194 DLLEXPORT typeCollection *Module::getModuleTypes()
195 {
196    Annotatable<typeCollection *, module_type_info_a,  true> &mtA = *this;
197    typeCollection *mt;
198
199    if(mtA.size()){
200        mt = mtA[0];
201        if (!mt) {
202            fprintf(stderr, "%s[%d]:  FIXME:  NULL type collection\n", FILE__, __LINE__);
203            return NULL;
204        }
205    }
206    else{
207        mt = typeCollection::getModTypeCollection(this);
208        mtA.addAnnotation(mt);
209    }
210    return mt;
211 }
212
213 DLLEXPORT bool Module::findType(Type *&type, std::string name)
214 {
215    exec_->parseTypesNow();
216    type = getModuleTypes()->findType(name);
217
218    if (type == NULL)
219       return false;
220
221    return true;
222 }
223
224 DLLEXPORT bool Module::findVariableType(Type *&type, std::string name)
225 {
226    exec_->parseTypesNow();
227    type = getModuleTypes()->findVariableType(name);
228
229    if (type == NULL)
230       return false;
231    return true;
232 }
233
234 void Symtab::parseTypesNow()
235 {
236    if (isTypeInfoValid_)
237       return;
238    parseTypes();
239 }
240
241 DLLEXPORT bool Module::setLineInfo(LineInformation *lineInfo)
242 {
243    Annotatable<LineInformation *, module_line_info_a,  true> &mt = *this;
244    if (mt.size()) {
245       // We need to remove the existing annotation and make sure there is only one annotation.
246       mt.clearAnnotations();
247       //fprintf(stderr, "%s[%d]:  WARNING, already have lineInfo set for module %s\n", FILE__, __LINE__, fileName_.c_str());
248    }
249    mt.addAnnotation(lineInfo);
250    return true;
251 }
252
253 DLLEXPORT bool Module::findLocalVariable(std::vector<localVar *>&vars, std::string name)
254 {
255    exec_->parseTypesNow();
256    std::vector<Symbol *>mod_funcs;
257
258    if (!getAllSymbolsByType(mod_funcs, Symbol::ST_FUNCTION))
259       return false;
260
261    unsigned origSize = vars.size();
262    for (unsigned int i=0;i<mod_funcs.size();i++)
263       mod_funcs[i]->findLocalVariable(vars, name);
264
265    if (vars.size()>origSize)
266       return true;
267
268    return false;
269 }
270
271 DLLEXPORT Module::Module(supportedLanguages lang, Offset adr,
272       std::string fullNm, Symtab *img) :
273    fullName_(fullNm),
274    language_(lang),
275    addr_(adr),
276    exec_(img)
277 {
278    fileName_ = extract_pathname_tail(fullNm);
279 }
280
281 DLLEXPORT Module::Module() :
282    fileName_(""),
283    fullName_(""),
284    language_(lang_Unknown),
285    addr_(0),
286    exec_(NULL)
287 {
288 }
289
290 DLLEXPORT Module::Module(const Module &mod) :
291    LookupInterface(),
292    Serializable(),
293    Annotatable<LineInformation *, module_line_info_a,  true>(),
294    Annotatable<typeCollection *, module_type_info_a,  true>(),
295    fileName_(mod.fileName_),
296    fullName_(mod.fullName_),
297    language_(mod.language_),
298    addr_(mod.addr_),
299    exec_(mod.exec_)
300 {
301    Annotatable<LineInformation *, module_line_info_a,  true> &liA = *this;
302    const Annotatable<LineInformation *, module_line_info_a,  true> &liA_src = mod;
303
304    if (liA_src.size()) {
305       LineInformation *li_src = liA_src[0];
306       assert(li_src);
307       liA.addAnnotation(li_src);
308    }
309 }
310
311 DLLEXPORT Module::~Module()
312 {
313    Annotatable<LineInformation *, module_line_info_a,  true> &liA = *this;
314    if (liA.size()){
315        delete liA[0];
316        liA.clearAnnotations();
317    }
318 }
319
320 bool Module::isShared() const
321 {
322    return !exec_->isExec();
323 }
324
325 bool Module::getAllSymbolsByType(std::vector<Symbol *> &found, Symbol::SymbolType sType)
326 {
327    unsigned orig_size = found.size();
328    std::vector<Symbol *> obj_syms;
329    if (!exec()->getAllSymbolsByType(obj_syms, sType))
330       return false;
331
332    for (unsigned i = 0; i < obj_syms.size(); i++) {
333       if (obj_syms[i]->getModule() == this)
334          found.push_back(obj_syms[i]);
335    }
336
337    if (found.size() > orig_size)
338       return true;
339
340    serr = No_Such_Symbol;
341    return false;
342 }
343
344 DLLEXPORT bool Module::operator==(const Module &mod) const
345 {
346    const Annotatable<LineInformation *, module_line_info_a,  true> *liA = this;
347    const Annotatable<LineInformation *, module_line_info_a,  true> *liA_src = &mod;
348    if (liA->size() != liA_src->size()) return false;
349    if (liA->size()) {
350       LineInformation *li = liA->getAnnotation(0);
351       LineInformation *li_src = liA_src->getAnnotation(0);
352       if ((li != li_src)) return false;
353    }
354
355    return (
356          (language_==mod.language_)
357          && (addr_==mod.addr_)
358          && (fullName_==mod.fullName_)
359          && (exec_==mod.exec_)
360          );
361 }
362
363 DLLEXPORT bool Module::setName(std::string newName)
364 {
365    fullName_ = newName;
366    fileName_ = extract_pathname_tail(fullName_);
367    return true;
368 }
369
370 DLLEXPORT void Module::setLanguage(supportedLanguages lang)
371 {
372    language_ = lang;
373 }
374
375 DLLEXPORT Offset Module::addr() const
376 {
377    return addr_;
378 }
379
380 DLLEXPORT bool Module::setDefaultNamespacePrefix(string str){
381     return exec_->setDefaultNamespacePrefix(str);
382 }
383
384 void Module::serialize(SerializerBase *sb, const char *tag)
385 {
386    ifxml_start_element(sb, tag);
387    gtranslate(sb, fileName_, "fileName");
388    gtranslate(sb, fullName_, "fullName");
389    gtranslate(sb, addr_, "Address");
390    gtranslate(sb, language_, supportedLanguages2Str, "Language");
391    ifxml_end_element(sb, tag);
392
393    //  Patch up exec_ (pointer to Symtab) at a higher level??
394    //if (getSD().iomode() == sd_deserialize)
395    //   param.exec_ = parent_symtab;
396 }
397