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