windows build fixes and some more work on symtab serialization
[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 <string.h>
32
33 #include "Annotatable.h"
34 #include "Module.h"
35 #include "Symtab.h"
36 #include "Collections.h"
37 #include "Function.h"
38 #include "Variable.h"
39
40 #include "common/h/pathName.h"
41 #include "common/h/serialize.h"
42
43 using namespace Dyninst;
44 using namespace Dyninst::SymtabAPI;
45 using namespace std;
46
47 static AnnotationClass<LineInformation> ModuleLineInfoAnno(std::string("ModuleLineInfoAnno"));
48 static AnnotationClass<typeCollection> ModuleTypeInfoAnno(std::string("ModuleTypeInfoAnno"));
49 static SymtabError serr;
50
51 bool Module::findSymbolByType(std::vector<Symbol *> &found, 
52       const std::string name,
53       Symbol::SymbolType sType, 
54       bool isMangled,
55       bool isRegex, 
56       bool checkCase)
57 {
58     return findSymbolByType(found,
59                             name,
60                             sType,
61                             isMangled ? mangledName : prettyName,
62                             isRegex,
63                             checkCase);
64 }
65
66 bool Module::findSymbolByType(std::vector<Symbol *> &found, 
67                               const std::string name,
68                               Symbol::SymbolType sType, 
69                               NameType nameType,
70                               bool isRegex,
71                               bool checkCase) {
72     unsigned orig_size = found.size();
73     std::vector<Symbol *> obj_syms;
74     
75     if (!exec()->findSymbolByType(obj_syms, name, sType, nameType, isRegex, checkCase)) {
76         //fprintf(stderr, "%s[%d]:  no symbols matching %s found\n", FILE__, __LINE__, name.c_str());
77         return false;
78     }
79     
80     for (unsigned i = 0; i < obj_syms.size(); i++) {
81         if (obj_syms[i]->getModule() == this)
82             found.push_back(obj_syms[i]);
83     }
84     
85     if (found.size() > orig_size) 
86         return true;
87     
88     return false;        
89 }
90
91 bool Module::getAllSymbols(std::vector<Symbol *> &found) {
92     unsigned orig_size = found.size();
93     std::vector<Symbol *> obj_syms;
94     
95     if (!exec()->getAllSymbols(obj_syms)) {
96         //fprintf(stderr, "%s[%d]:  no symbols matching %s found\n", FILE__, __LINE__, name.c_str());
97         return false;
98     }
99     
100     for (unsigned i = 0; i < obj_syms.size(); i++) {
101         if (obj_syms[i]->getModule() == this)
102             found.push_back(obj_syms[i]);
103     }
104     
105     if (found.size() > orig_size) 
106         return true;
107     
108     return false;        
109 }
110
111 const std::string &Module::fileName() const
112 {
113    return fileName_;
114 }
115
116 const std::string &Module::fullName() const
117 {
118    return fullName_;
119 }
120
121  Symtab *Module::exec() const
122 {
123    return exec_;
124 }
125
126 supportedLanguages Module::language() const
127 {
128    return language_;
129 }
130
131 bool Module::hasLineInformation()
132 {
133    LineInformation *li =  NULL;
134    if (getAnnotation(li, ModuleLineInfoAnno)) 
135    {
136       if (!li) 
137       {
138          fprintf(stderr, "%s[%d]:  weird inconsistency with getAnnotation here\n", 
139                FILE__, __LINE__);
140          return false;
141       }
142
143       if (li->getSize())
144       {
145          return true;
146       }
147    }
148
149    return false;
150 }
151
152 LineInformation *Module::getLineInformation()
153 {
154    if (!exec_->isLineInfoValid_)
155       exec_->parseLineInformation();
156
157    if (!exec_->isLineInfoValid_) 
158    {
159       return NULL;
160    }
161
162    LineInformation *li =  NULL;
163    if (getAnnotation(li, ModuleLineInfoAnno)) 
164    {
165       if (!li) 
166       {
167          fprintf(stderr, "%s[%d]:  weird inconsistency with getAnnotation here\n", 
168                FILE__, __LINE__);
169          return NULL;
170       }
171
172       if (!li->getSize())
173       {
174          return NULL;
175       }
176    }
177
178    return li;
179 }
180
181 bool Module::getAddressRanges(std::vector<pair<Offset, Offset> >&ranges,
182       std::string lineSource, unsigned int lineNo)
183 {
184    unsigned int originalSize = ranges.size();
185
186    LineInformation *lineInformation = getLineInformation();
187    if (lineInformation)
188       lineInformation->getAddressRanges( lineSource.c_str(), lineNo, ranges );
189
190    if ( ranges.size() != originalSize )
191       return true;
192
193    fprintf(stderr, "%s[%d]:  failing to getAddressRanges fr %s[%d]\n", FILE__, __LINE__, lineSource.c_str(), lineNo);
194
195    return false;
196 }
197
198 bool Module::getSourceLines(std::vector<LineNoTuple> &lines, Offset addressInRange)
199 {
200    unsigned int originalSize = lines.size();
201
202    LineInformation *lineInformation = getLineInformation();
203    if (lineInformation)
204       lineInformation->getSourceLines( addressInRange, lines );
205
206    if ( lines.size() != originalSize )
207       return true;
208
209    return false;
210 }
211
212 vector<Type *> *Module::getAllTypes()
213 {
214    typeCollection *tc = NULL;
215    if (!getAnnotation(tc, ModuleTypeInfoAnno))
216    {
217 #if 0
218       tc = new typeCollection();
219       if (!addAnnotation(tc, ModuleTypeInfoAnno))
220       {
221          fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
222          return NULL;
223       }
224 #endif
225       return NULL;
226    }
227    if (!tc)
228    {
229       fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
230       return NULL;
231    }
232
233    return tc->getAllTypes();
234 }
235
236 vector<pair<string, Type *> > *Module::getAllGlobalVars()
237 {
238
239    typeCollection *tc = NULL;
240    if (!getAnnotation(tc, ModuleTypeInfoAnno))
241    {
242 #if 0
243       tc = new typeCollection();
244       if (!addAnnotation(tc, ModuleTypeInfoAnno))
245       {
246          fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
247          return NULL;
248       }
249 #endif
250       return NULL;
251    }
252    if (!tc)
253    {
254       fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
255       return NULL;
256    }
257
258    return tc->getAllGlobalVariables();
259 }
260
261 typeCollection *Module::getModuleTypes()
262 {
263    typeCollection *tc = NULL;
264    if (!getAnnotation(tc, ModuleTypeInfoAnno))
265    {
266       //  add an empty type collection (to be filled in later)
267       tc = new typeCollection();
268       if (!addAnnotation(tc, ModuleTypeInfoAnno))
269       {
270          fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
271          return NULL;
272       }
273
274       return tc;
275    }
276
277    if (!tc)
278    {
279       fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
280       return NULL;
281    }
282
283    return tc;
284 }
285
286 bool Module::findType(Type *&type, std::string name)
287 {
288    exec_->parseTypesNow();
289    type = getModuleTypes()->findType(name);
290
291    if (type == NULL)
292       return false;
293
294    return true;
295 }
296
297 bool Module::findVariableType(Type *&type, std::string name)
298 {
299    exec_->parseTypesNow();
300    type = getModuleTypes()->findVariableType(name);
301
302    if (type == NULL)
303       return false;
304
305    return true;
306 }
307
308
309 bool Module::setLineInfo(LineInformation *lineInfo)
310 {
311    LineInformation *li =  NULL;
312
313    if (!getAnnotation(li, ModuleLineInfoAnno)) 
314    {
315       if (li) 
316       {
317          return false;
318       }
319
320       if (!addAnnotation(lineInfo, ModuleLineInfoAnno))
321       {
322          return false;
323       }
324
325       return true;
326    }
327    if (li != lineInfo)
328      delete li;
329    
330    if (!addAnnotation(lineInfo, ModuleLineInfoAnno))
331    {
332      fprintf(stderr, "%s[%d]:  failed to add lineInfo annotation\n", FILE__, __LINE__);
333      return false;
334    }
335
336    return false;
337 }
338
339 bool Module::findLocalVariable(std::vector<localVar *>&vars, std::string name)
340 {
341    exec_->parseTypesNow();
342    std::vector<Function *>mod_funcs;
343
344    if (!exec_->getAllFunctions(mod_funcs))
345    {
346       return false;
347    }
348
349    unsigned origSize = vars.size();
350
351    for (unsigned int i = 0; i < mod_funcs.size(); i++)
352    {
353       mod_funcs[i]->findLocalVariable(vars, name);
354    }
355
356    if (vars.size() > origSize)
357       return true;
358
359    return false;
360 }
361
362 Module::Module(supportedLanguages lang, Offset adr,
363       std::string fullNm, Symtab *img) :
364    fullName_(fullNm),
365    language_(lang),
366    addr_(adr),
367    exec_(img)
368 {
369    fileName_ = extract_pathname_tail(fullNm);
370 }
371
372 Module::Module() :
373    fileName_(""),
374    fullName_(""),
375    language_(lang_Unknown),
376    addr_(0),
377    exec_(NULL)
378 {
379 }
380
381 Module::Module(const Module &mod) :
382    LookupInterface(),
383    Serializable(),
384    AnnotatableSparse(),
385    fileName_(mod.fileName_),
386    fullName_(mod.fullName_),
387    language_(mod.language_),
388    addr_(mod.addr_),
389    exec_(mod.exec_)
390 {
391    //  Copy annotations here or no?
392 }
393
394 Module::~Module()
395 {
396 }
397
398 bool Module::isShared() const
399 {
400    return !exec_->isExec();
401 }
402
403 bool Module::getAllSymbolsByType(std::vector<Symbol *> &found, Symbol::SymbolType sType)
404 {
405    unsigned orig_size = found.size();
406    std::vector<Symbol *> obj_syms;
407
408    if (!exec()->getAllSymbolsByType(obj_syms, sType))
409       return false;
410
411    for (unsigned i = 0; i < obj_syms.size(); i++) 
412    {
413       if (obj_syms[i]->getModule() == this)
414          found.push_back(obj_syms[i]);
415    }
416
417    if (found.size() > orig_size)
418    {
419       return true;
420    }
421
422    serr = No_Such_Symbol;
423    return false;
424 }
425
426 bool Module::getAllFunctions(std::vector<Function *> &ret)
427 {
428     return exec()->getAllFunctions(ret);
429 }
430
431 bool Module::operator==(Module &mod) 
432 {
433    LineInformation *li =  NULL;
434    LineInformation *li_src =  NULL;
435    bool get_anno_res = false, get_anno_res_src = false;
436    get_anno_res = getAnnotation(li, ModuleLineInfoAnno);
437    get_anno_res_src = mod.getAnnotation(li_src, ModuleLineInfoAnno);
438
439    if (get_anno_res != get_anno_res_src)
440    {
441       fprintf(stderr, "%s[%d]:  weird inconsistency with getAnnotation here\n", 
442             FILE__, __LINE__);
443       return false;
444    }
445
446    if (li) 
447    {
448       if (!li_src) 
449       {
450          fprintf(stderr, "%s[%d]:  weird inconsistency with getAnnotation here\n", 
451                FILE__, __LINE__);
452          return false;
453       }
454
455       if (li->getSize() != li_src->getSize()) 
456          return false;
457
458       if ((li != li_src)) 
459          return false;
460    }
461    else
462    {
463       if (li_src) 
464       {
465          fprintf(stderr, "%s[%d]:  weird inconsistency with getAnnotation here\n", 
466                FILE__, __LINE__);
467          return false;
468       }
469    }
470
471    return (
472          (language_==mod.language_)
473          && (addr_==mod.addr_)
474          && (fullName_==mod.fullName_)
475          && (exec_==mod.exec_)
476          );
477 }
478
479 bool Module::setName(std::string newName)
480 {
481    fullName_ = newName;
482    fileName_ = extract_pathname_tail(fullName_);
483    return true;
484 }
485
486 void Module::setLanguage(supportedLanguages lang)
487 {
488    language_ = lang;
489 }
490
491 Offset Module::addr() const
492 {
493    return addr_;
494 }
495
496 bool Module::setDefaultNamespacePrefix(string str)
497 {
498     return exec_->setDefaultNamespacePrefix(str);
499 }
500
501 void Module::serialize(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
502 {
503    ifxml_start_element(sb, tag);
504    gtranslate(sb, fileName_, "fileName");
505    gtranslate(sb, fullName_, "fullName");
506    gtranslate(sb, addr_, "Address");
507    gtranslate(sb, (int &) language_, "Language");
508    ifxml_end_element(sb, tag);
509
510    if (sb->isInput())
511    {
512            ScopedSerializerBase<Symtab> *ssb = dynamic_cast<ScopedSerializerBase<Symtab> *>(sb);
513            if (!ssb)
514            {
515                    fprintf(stderr, "%s[%d]:  FIXME\n", FILE__, __LINE__);
516                    SER_ERR("dynamic_cast");
517            }
518
519            Symtab *st = ssb->getScope();
520            if (!st)
521            {
522                    fprintf(stderr, "%s[%d]:  FIXME\n", FILE__, __LINE__);
523                    SER_ERR("getScope");
524            }
525
526            exec_ = st;
527    }
528 }
529
530 bool Module::findVariablesByName(std::vector<Variable *> &ret, const std::string name,
531                                  NameType nameType,
532                                  bool isRegex,
533                                  bool checkCase) {
534   bool succ = false;
535   std::vector<Variable *> tmp;
536
537   if (!exec()->findVariablesByName(tmp, name, nameType, isRegex, checkCase)) {
538     return false;
539   }
540   for (unsigned i = 0; i < tmp.size(); i++) {
541     if (tmp[i]->getModule() == this) {
542       ret.push_back(tmp[i]);
543       succ = true;
544     }
545   }
546   return succ;
547 }
548