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