Windows test suite & build fixes. VC2003 and VC2008 should both now build. Known...
[dyninst.git] / symtabAPI / src / Aggregate.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
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
30  */
31
32 #include "Annotatable.h"
33 #include "common/h/serialize.h"
34
35 #include "Symtab.h"
36 #include "symutil.h"
37 #include "Module.h"
38 #include "Collections.h"
39
40 #include "symtabAPI/src/Object.h"
41
42
43 #include "Aggregate.h"
44 #include "Symbol.h"
45
46 using namespace std;
47 using namespace Dyninst;
48 using namespace Dyninst::SymtabAPI;
49
50 Aggregate::Aggregate() : module_(NULL)
51 {}
52
53 Offset Aggregate::getAddress() const {
54     return symbols_[0]->getAddr();
55 }
56
57 Module *Aggregate::getModule() const {
58     return module_;
59 }
60
61 const vector<std::string> &Aggregate::getAllMangledNames() {
62     return mangledNames_;
63 }
64 const vector<std::string> &Aggregate::getAllPrettyNames() {
65     return prettyNames_;
66 }
67 const vector<std::string> &Aggregate::getAllTypedNames() {
68     return typedNames_;
69 }
70
71 bool Aggregate::addSymbol(Symbol *sym) {
72
73     // We keep a "primary" module, which is defined as "anything not DEFAULT_MODULE".
74     if (module_ == NULL) {
75         module_ = sym->getModule();
76     }
77     else if (module_->fileName() == "DEFAULT_MODULE") {
78         module_ = sym->getModule();
79     }
80     // else keep current module.
81
82     symbols_.push_back(sym);
83
84     // We need to add the symbol names (if they aren't there already)
85     // We can have multiple identical names - for example, there are
86     // often two symbols for main (static and dynamic symbol table)
87     
88     bool found = false;
89     for (unsigned j = 0; j < mangledNames_.size(); j++) {
90         if (sym->getMangledName() == mangledNames_[j]) {
91             found = true;
92             break;
93         }
94     }
95     if (!found) mangledNames_.push_back(sym->getMangledName());
96
97     found = false;
98
99     for (unsigned j = 0; j < prettyNames_.size(); j++) {
100         if (sym->getPrettyName() == prettyNames_[j]) {
101             found = true;
102             break;
103         }
104     }
105     if (!found) prettyNames_.push_back(sym->getPrettyName());
106
107     found = false;
108     for (unsigned j = 0; j < typedNames_.size(); j++) {
109         if (sym->getTypedName() == typedNames_[j]) {
110             found = true;
111             break;
112         }
113     }
114     if (!found) typedNames_.push_back(sym->getTypedName());;
115
116     return true;
117 }
118
119 bool Aggregate::removeSymbol(Symbol *sym) {
120     std::vector<Symbol *>::iterator iter;
121     for (iter = symbols_.begin(); iter != symbols_.end(); iter++) {
122         if (*iter == sym) {
123             symbols_.erase(iter);
124             return true;
125         }
126     }
127     // TODO: remove from names. Do we ever call this?
128
129     return false;
130 }
131
132 bool Aggregate::getAllSymbols(std::vector<Symbol *> &syms) const 
133 {
134     syms = symbols_;
135     return true;
136 }
137
138 Symbol * Aggregate::getFirstSymbol() const
139 {
140     assert( symbols_.size()>0 );
141     return symbols_[0];
142 }
143
144 SYMTAB_EXPORT bool Aggregate::addMangledName(string name, bool isPrimary) 
145  {
146     // Check to see if we're duplicating
147     for (unsigned i = 0; i < mangledNames_.size(); i++) {
148         if (mangledNames_[i] == name)
149             return false;
150     }
151
152     if (isPrimary) {
153         std::vector<std::string>::iterator iter = mangledNames_.begin();
154         mangledNames_.insert(iter, name);
155     }
156     else
157         mangledNames_.push_back(name);
158
159     if (addMangledNameInt(name, isPrimary) == false) return false;
160      return true;
161  }                                                                                                                                      
162  
163  SYMTAB_EXPORT bool Aggregate::addPrettyName(string name, bool isPrimary) 
164  {
165     // Check to see if we're duplicating
166     for (unsigned i = 0; i < prettyNames_.size(); i++) {
167         if (prettyNames_[i] == name)
168             return false;
169     }
170
171     if (isPrimary) {
172         std::vector<std::string>::iterator iter = prettyNames_.begin();
173         prettyNames_.insert(iter, name);
174     }
175     else
176         prettyNames_.push_back(name);
177     if (addPrettyNameInt(name, isPrimary) == false) return false;
178      return true;
179  }                                                                                                                                      
180  
181  SYMTAB_EXPORT bool Aggregate::addTypedName(string name, bool isPrimary) 
182  {
183     // Check to see if we're duplicating
184     for (unsigned i = 0; i < typedNames_.size(); i++) {
185         if (typedNames_[i] == name)
186             return false;
187     }
188     if (addTypedNameInt(name, isPrimary) == false) return false;
189
190     if (isPrimary) {
191         std::vector<std::string>::iterator iter = typedNames_.begin();
192         typedNames_.insert(iter, name);
193     }
194     else
195         typedNames_.push_back(name);
196         return true;
197  }
198
199 bool Aggregate::addMangledNameInt(string name, bool isPrimary) {
200     // Check to see if we're duplicating
201     for (unsigned i = 0; i < mangledNames_.size(); i++) {
202         if (mangledNames_[i] == name)
203             return false;
204     }
205
206     if (isPrimary) {
207         std::vector<std::string>::iterator iter = mangledNames_.begin();
208         mangledNames_.insert(iter, name);
209     }
210     else
211         mangledNames_.push_back(name);
212     return true;
213 }
214
215 bool Aggregate::addPrettyNameInt(string name, bool isPrimary) {
216     // Check to see if we're duplicating
217     for (unsigned i = 0; i < prettyNames_.size(); i++) {
218         if (prettyNames_[i] == name)
219             return false;
220     }
221
222     if (isPrimary) {
223         std::vector<std::string>::iterator iter = prettyNames_.begin();
224         prettyNames_.insert(iter, name);
225     }
226     else
227         prettyNames_.push_back(name);
228     return true;
229 }
230
231 bool Aggregate::addTypedNameInt(string name, bool isPrimary) {
232     // Check to see if we're duplicating
233     for (unsigned i = 0; i < typedNames_.size(); i++) {
234         if (typedNames_[i] == name)
235             return false;
236     }
237
238     if (isPrimary) {
239         std::vector<std::string>::iterator iter = typedNames_.begin();
240         typedNames_.insert(iter, name);
241     }
242     else
243         typedNames_.push_back(name);
244     return true;
245 }
246