pre-update
[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 }
128
129 LineInformation *Module::getLineInformation()
130 {
131    if (!exec_->isLineInfoValid_)
132       exec_->parseLineInformation();
133
134    if (!exec_->isLineInfoValid_) 
135    {
136       return NULL;
137    }
138
139    LineInformation *li =  NULL;
140    if (getAnnotation(li, ModuleLineInfoAnno)) 
141    {
142       if (!li) 
143       {
144          fprintf(stderr, "%s[%d]:  weird inconsistency with getAnnotation here\n", 
145                FILE__, __LINE__);
146          return NULL;
147       }
148
149       if (!li->getSize())
150       {
151          return NULL;
152       }
153    }
154
155    return li;
156 }
157
158 bool Module::getAddressRanges(std::vector<pair<Offset, Offset> >&ranges,
159       std::string lineSource, unsigned int lineNo)
160 {
161    unsigned int originalSize = ranges.size();
162
163    LineInformation *lineInformation = getLineInformation();
164    if (lineInformation)
165       lineInformation->getAddressRanges( lineSource.c_str(), lineNo, ranges );
166
167    if ( ranges.size() != originalSize )
168       return true;
169
170    fprintf(stderr, "%s[%d]:  failing to getAddressRanges fr %s[%d]\n", FILE__, __LINE__, lineSource.c_str(), lineNo);
171
172    return false;
173 }
174
175 bool Module::getSourceLines(std::vector<LineNoTuple> &lines, Offset addressInRange)
176 {
177    unsigned int originalSize = lines.size();
178
179    LineInformation *lineInformation = getLineInformation();
180    if (lineInformation)
181       lineInformation->getSourceLines( addressInRange, lines );
182
183    if ( lines.size() != originalSize )
184       return true;
185
186    return false;
187 }
188
189 vector<Type *> *Module::getAllTypes()
190 {
191    typeCollection *tc = NULL;
192    if (!getAnnotation(tc, ModuleTypeInfoAnno))
193    {
194 #if 0
195       tc = new typeCollection();
196       if (!addAnnotation(tc, ModuleTypeInfoAnno))
197       {
198          fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
199          return NULL;
200       }
201 #endif
202       return NULL;
203    }
204    if (!tc)
205    {
206       fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
207       return NULL;
208    }
209
210    return tc->getAllTypes();
211 }
212
213 vector<pair<string, Type *> > *Module::getAllGlobalVars()
214 {
215
216    typeCollection *tc = NULL;
217    if (!getAnnotation(tc, ModuleTypeInfoAnno))
218    {
219 #if 0
220       tc = new typeCollection();
221       if (!addAnnotation(tc, ModuleTypeInfoAnno))
222       {
223          fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
224          return NULL;
225       }
226 #endif
227       return NULL;
228    }
229    if (!tc)
230    {
231       fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
232       return NULL;
233    }
234
235    return tc->getAllGlobalVariables();
236 }
237
238 typeCollection *Module::getModuleTypes()
239 {
240    typeCollection *tc = NULL;
241    if (!getAnnotation(tc, ModuleTypeInfoAnno))
242    {
243       //  add an empty type collection (to be filled in later)
244       tc = new typeCollection();
245       if (!addAnnotation(tc, ModuleTypeInfoAnno))
246       {
247          fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
248          return NULL;
249       }
250
251       return tc;
252    }
253
254    if (!tc)
255    {
256       fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
257       return NULL;
258    }
259
260    return tc;
261 }
262
263 bool Module::findType(Type *&type, std::string name)
264 {
265    exec_->parseTypesNow();
266    type = getModuleTypes()->findType(name);
267
268    if (type == NULL)
269       return false;
270
271    return true;
272 }
273
274 bool Module::findVariableType(Type *&type, std::string name)
275 {
276    exec_->parseTypesNow();
277    type = getModuleTypes()->findVariableType(name);
278
279    if (type == NULL)
280       return false;
281
282    return true;
283 }
284
285 void Symtab::parseTypesNow()
286 {
287    if (isTypeInfoValid_)
288       return;
289
290    parseTypes();
291 }
292
293 bool Module::setLineInfo(LineInformation *lineInfo)
294 {
295    LineInformation *li =  NULL;
296
297    if (!getAnnotation(li, ModuleLineInfoAnno)) 
298    {
299       if (li) 
300       {
301          return false;
302       }
303
304       if (!addAnnotation(lineInfo, ModuleLineInfoAnno))
305       {
306          return false;
307       }
308
309       return true;
310    }
311    if (li != lineInfo)
312      delete li;
313    
314    if (!addAnnotation(lineInfo, ModuleLineInfoAnno))
315    {
316      fprintf(stderr, "%s[%d]:  failed to add lineInfo annotation\n", FILE__, __LINE__);
317      return false;
318    }
319
320    return false;
321 }
322
323 bool Module::findLocalVariable(std::vector<localVar *>&vars, std::string name)
324 {
325    exec_->parseTypesNow();
326    std::vector<Function *>mod_funcs;
327
328    if (!exec_->getAllFunctions(mod_funcs))
329    {
330       return false;
331    }
332
333    unsigned origSize = vars.size();
334
335    for (unsigned int i = 0; i < mod_funcs.size(); i++)
336    {
337       mod_funcs[i]->findLocalVariable(vars, name);
338    }
339
340    if (vars.size() > origSize)
341       return true;
342
343    return false;
344 }
345
346 Module::Module(supportedLanguages lang, Offset adr,
347       std::string fullNm, Symtab *img) :
348    fullName_(fullNm),
349    language_(lang),
350    addr_(adr),
351    exec_(img)
352 {
353    fileName_ = extract_pathname_tail(fullNm);
354 }
355
356 Module::Module() :
357    fileName_(""),
358    fullName_(""),
359    language_(lang_Unknown),
360    addr_(0),
361    exec_(NULL)
362 {
363 }
364
365 Module::Module(const Module &mod) :
366    LookupInterface(),
367    Serializable(),
368    AnnotatableSparse(),
369    fileName_(mod.fileName_),
370    fullName_(mod.fullName_),
371    language_(mod.language_),
372    addr_(mod.addr_),
373    exec_(mod.exec_)
374 {
375    //  Copy annotations here or no?
376 }
377
378 Module::~Module()
379 {
380
381    //  individual deletion of annotations??
382
383 #if 0
384    if (!clearAnnotations()) 
385    {
386       fprintf(stderr, "%s[%d]:  failed to clear annotations\n", FILE__, __LINE__);
387    }
388 #endif
389    //fprintf(stderr, "%s[%d]:  FIXME:  need to clear annotations??\n", FILE__, __LINE__);
390
391 }
392
393 bool Module::isShared() const
394 {
395    return !exec_->isExec();
396 }
397
398 bool Module::getAllSymbolsByType(std::vector<Symbol *> &found, Symbol::SymbolType sType)
399 {
400    unsigned orig_size = found.size();
401    std::vector<Symbol *> obj_syms;
402
403    if (!exec()->getAllSymbolsByType(obj_syms, sType))
404       return false;
405
406    for (unsigned i = 0; i < obj_syms.size(); i++) 
407    {
408       if (obj_syms[i]->getModule() == this)
409          found.push_back(obj_syms[i]);
410    }
411
412    if (found.size() > orig_size)
413    {
414       return true;
415    }
416
417    serr = No_Such_Symbol;
418    return false;
419 }
420
421 bool Module::getAllFunctions(std::vector<Function *> &ret)
422 {
423     return exec()->getAllFunctions(ret);
424 }
425
426 bool Module::operator==(Module &mod) 
427 {
428    LineInformation *li =  NULL;
429    LineInformation *li_src =  NULL;
430    bool get_anno_res = false, get_anno_res_src = false;
431    get_anno_res = getAnnotation(li, ModuleLineInfoAnno);
432    get_anno_res_src = mod.getAnnotation(li_src, ModuleLineInfoAnno);
433
434    if (get_anno_res != get_anno_res_src)
435    {
436       fprintf(stderr, "%s[%d]:  weird inconsistency with getAnnotation here\n", 
437             FILE__, __LINE__);
438       return false;
439    }
440
441    if (li) 
442    {
443       if (!li_src) 
444       {
445          fprintf(stderr, "%s[%d]:  weird inconsistency with getAnnotation here\n", 
446                FILE__, __LINE__);
447          return false;
448       }
449
450       if (li->getSize() != li_src->getSize()) 
451          return false;
452
453       if ((li != li_src)) 
454          return false;
455    }
456    else
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
466    return (
467          (language_==mod.language_)
468          && (addr_==mod.addr_)
469          && (fullName_==mod.fullName_)
470          && (exec_==mod.exec_)
471          );
472 }
473
474 bool Module::setName(std::string newName)
475 {
476    fullName_ = newName;
477    fileName_ = extract_pathname_tail(fullName_);
478    return true;
479 }
480
481 void Module::setLanguage(supportedLanguages lang)
482 {
483    language_ = lang;
484 }
485
486 Offset Module::addr() const
487 {
488    return addr_;
489 }
490
491 bool Module::setDefaultNamespacePrefix(string str)
492 {
493     return exec_->setDefaultNamespacePrefix(str);
494 }
495
496 void Module::serialize(SerializerBase *sb, const char *tag)
497 {
498    ifxml_start_element(sb, tag);
499    gtranslate(sb, fileName_, "fileName");
500    gtranslate(sb, fullName_, "fullName");
501    gtranslate(sb, addr_, "Address");
502    gtranslate(sb, language_, supportedLanguages2Str, "Language");
503    ifxml_end_element(sb, tag);
504
505    //  Patch up exec_ (pointer to Symtab) at a higher level??
506    //if (getSD().iomode() == sd_deserialize)
507    //   param.exec_ = parent_symtab;
508 }
509