windows build fixes and some more work on symtab serialization
[dyninst.git] / symtabAPI / src / Function.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 // $Id: Object.C,v 1.31 2008/11/03 15:19:25 jaw Exp $
33
34 #include "Annotatable.h"
35 #include "common/h/serialize.h"
36
37 #include "Symtab.h"
38 #include "symutil.h"
39 #include "Module.h"
40 #include "Collections.h"
41 #include "Function.h"
42
43 #include "symtabAPI/src/Object.h"
44
45 #include "annotations.h"
46
47 #include <iostream>
48
49 using namespace std;
50 using namespace Dyninst;
51 using namespace Dyninst::SymtabAPI;
52
53 Function::Function(Symbol *sym)
54     : Aggregate(sym),
55       retType_(NULL), 
56       framePtrRegNum_(-1)
57 {}
58
59 Type * Function::getReturnType() const
60 {
61     return retType_;
62 }
63
64 bool Function::setReturnType(Type *newType)
65 {
66     retType_ = newType;
67     return true;
68 }
69
70 int Function::getFramePtrRegnum() const
71 {
72     return framePtrRegNum_;
73 }
74
75 bool Function::setFramePtrRegnum(int regnum)
76 {
77     framePtrRegNum_ = regnum;
78     return true;
79 }
80
81 std::vector<Dyninst::SymtabAPI::VariableLocation> *Function::getFramePtr() 
82 {
83     return &locs_;
84 }
85
86 //bool Function::setFramePtr(vector<loc_t> *locs) 
87 //{
88  //   if (locs_) 
89  //       return false;
90 //    
91 //    locs_ = locs;
92 //    return true;
93 //}
94
95
96 bool Function::findLocalVariable(std::vector<localVar *> &vars, std::string name)
97 {
98    module_->exec()->parseTypesNow();    
99
100    localVarCollection *lvs = NULL, *lps = NULL;
101    bool res1 = false, res2 = false;
102    res1 = getAnnotation(lvs, FunctionLocalVariablesAnno);
103    res2 = getAnnotation(lps, FunctionParametersAnno);
104
105    if (!res1 && !res2)
106       return false;
107
108    unsigned origSize = vars.size();     
109
110    if (lvs)
111    {
112       localVar *var = lvs->findLocalVar(name);
113       if (var) 
114          vars.push_back(var);
115    }
116
117    if (lps)
118    {
119       localVar *var = lps->findLocalVar(name);
120       if (var) 
121          vars.push_back(var);
122    }
123
124    if (vars.size() > origSize)
125       return true;
126
127    return false;
128 }
129
130 bool Function::getLocalVariables(std::vector<localVar *> &vars)
131 {
132    module_->exec()->parseTypesNow();    
133
134    localVarCollection *lvs = NULL;
135    if (!getAnnotation(lvs, FunctionLocalVariablesAnno))
136    {
137       return false;
138    }
139    if (!lvs)
140    {
141       fprintf(stderr, "%s[%d]:  FIXME:  NULL ptr for annotation\n", FILE__, __LINE__);
142       return false;
143    }
144
145    vars = *(lvs->getAllVars());
146
147    if (vars.size())
148       return true;
149    return false;
150 }
151
152 bool Function::getParams(std::vector<localVar *> &params)
153 {
154    module_->exec()->parseTypesNow();    
155
156    localVarCollection *lvs = NULL;
157    if (!getAnnotation(lvs, FunctionParametersAnno))
158    {
159       return false;
160    }
161
162    if (!lvs)
163    {
164       fprintf(stderr, "%s[%d]:  FIXME:  NULL ptr for annotation\n", FILE__, __LINE__);
165       return false;
166    }
167
168    params = *(lvs->getAllVars());
169
170    if (params.size())
171       return true;
172    return false;
173 }
174
175 bool Function::addLocalVar(localVar *locVar)
176 {
177    localVarCollection *lvs = NULL;
178
179    if (!getAnnotation(lvs, FunctionLocalVariablesAnno))
180    {
181       lvs = new localVarCollection();
182
183       if (!addAnnotation(lvs, FunctionLocalVariablesAnno))
184       {
185          fprintf(stderr, "%s[%d]:  failed to add local var collecton anno\n", 
186                FILE__, __LINE__);
187          return false;
188       }
189    }
190
191    lvs->addLocalVar(locVar);
192    return true;
193 }
194
195 bool Function::addParam(localVar *param)
196 {
197         localVarCollection *ps = NULL;
198
199         if (!getAnnotation(ps, FunctionParametersAnno))
200         {
201                 ps = new localVarCollection();
202
203                 if (!addAnnotation(ps, FunctionParametersAnno))
204                 {
205                         fprintf(stderr, "%s[%d]:  failed to add local var collecton anno\n", 
206                                         FILE__, __LINE__);
207                         return false;
208                 }
209         }
210
211         ps->addLocalVar(param);
212
213         return true;
214 }
215
216 Function::~Function()
217 {
218 }
219
220 void Function::serialize(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
221 {
222         fprintf(stderr, "%s[%d]:  welcome to Function::serialize\n", FILE__, __LINE__);
223         if (!sb)
224         {
225                 SER_ERR("bad paramater sb");
226         }
227
228         //  Use typeID as unique identifier
229         unsigned int t_id = retType_ ? retType_->getID() : (unsigned int) 0xdeadbeef;
230
231         try
232         {
233                 ifxml_start_element(sb, tag);
234                 gtranslate(sb, t_id, "typeID");
235                 gtranslate(sb, framePtrRegNum_, "framePointerRegister");
236                 gtranslate(sb, locs_, "framePointerLocationList");
237                 Aggregate::serialize_aggregate(sb);
238                 ifxml_end_element(sb, tag);
239                 restore_type_by_id(sb, retType_, t_id);
240         }
241         SER_CATCH(tag);
242
243 }
244
245 bool Function::removeSymbol(Symbol *sym) 
246 {
247         removeSymbolInt(sym);
248         if (symbols_.empty()) {
249                 module_->exec()->deleteFunction(this);
250         }
251         return true;
252 }
253
254 std::ostream &operator<<(std::ostream &os, const Dyninst::SymtabAPI::VariableLocation &l)
255 {
256         const char *stc = storageClass2Str(l.stClass);
257         const char *strc = storageRefClass2Str(l.refClass);
258         os << "{"
259                 << "storageClass=" << stc
260                 << " storageRefClass=" << strc
261                 << " reg=" << l.reg
262                 << " frameOffset=" << l.frameOffset
263                 << " lowPC=" << l.lowPC
264                 << " hiPC=" << l.hiPC
265                 << "}";
266         return os;
267 }
268
269 std::ostream &operator<<(std::ostream &os, const Dyninst::SymtabAPI::Function &f)
270 {
271         std::string tname(f.retType_ ? f.retType_->getName() : "no_type");
272         const Aggregate *ag = dynamic_cast<const Aggregate *>(&f);
273         assert(ag);
274
275         os  << "Function{"
276                 << " type=" << tname
277                 << " framePtrRegNum_=" << f.framePtrRegNum_
278                 << " FramePtrLocationList=[";
279         for (unsigned int i = 0; i < f.locs_.size(); ++i)
280         {
281                 os << f.locs_[i]; 
282                 if ( (i + 1) < f.locs_.size())
283                         os << ", ";
284         }
285         os  << "] ";
286         os  <<  *ag;
287         os  <<  "}";
288         return os;
289
290 }
291
292 bool Function::operator==(const Function &f)
293 {
294         if (retType_ && !f.retType_)
295                 return false;
296         if (!retType_ && f.retType_)
297                 return false;
298         if (retType_)
299                 if (retType_->getID() != f.retType_->getID())
300                 {
301                         return false;
302                 }
303
304         if (framePtrRegNum_ != f.framePtrRegNum_)
305                 return false;
306
307         if (locs_.size() != f.locs_.size())
308                 return false;
309
310         for (unsigned int i = 0; i < locs_.size(); ++i)
311         {
312                 if (locs_[i] == locs_[i])
313                         return false;
314         }
315
316         return ((Aggregate &)(*this)) == ((Aggregate &)f);
317 }
318