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