Update copyright to LGPL on all files
[dyninst.git] / symtabAPI / src / Function.C
1 /*
2  * Copyright (c) 1996-2009 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       locs_(NULL),
58       functionSize_(0)
59 {}
60
61 Function::Function()
62     : Aggregate(),
63       retType_(NULL), 
64       framePtrRegNum_(-1),
65       locs_(NULL),
66       functionSize_(0)
67 {}
68
69 Type * Function::getReturnType() const
70 {
71     return retType_;
72 }
73
74 bool Function::setReturnType(Type *newType)
75 {
76     retType_ = newType;
77     return true;
78 }
79
80 int Function::getFramePtrRegnum() const
81 {
82     return framePtrRegNum_;
83 }
84
85 bool Function::setFramePtrRegnum(int regnum)
86 {
87     framePtrRegNum_ = regnum;
88     return true;
89 }
90
91 static std::vector<Dyninst::SymtabAPI::VariableLocation> emptyLocVec;
92 std::vector<Dyninst::SymtabAPI::VariableLocation> &Function::getFramePtr() 
93 {
94         if (locs_) return *locs_;
95         return emptyLocVec;
96 }
97
98 #if 0
99 bool Function::addLocation(VariableLocation &loc)
100 {
101         locs_.push_back(loc);
102     return true;
103 }
104 #endif
105 #if 1 
106 bool Function::setFramePtr(vector<VariableLocation> *locs) 
107 {
108     if (locs_) 
109         return false;
110     
111     locs_ = locs;
112     return true;
113 }
114 #endif
115
116
117 bool Function::findLocalVariable(std::vector<localVar *> &vars, std::string name)
118 {
119    module_->exec()->parseTypesNow();    
120
121    localVarCollection *lvs = NULL, *lps = NULL;
122    bool res1 = false, res2 = false;
123    res1 = getAnnotation(lvs, FunctionLocalVariablesAnno);
124    res2 = getAnnotation(lps, FunctionParametersAnno);
125
126    if (!res1 && !res2)
127       return false;
128
129    unsigned origSize = vars.size();     
130
131    if (lvs)
132    {
133       localVar *var = lvs->findLocalVar(name);
134       if (var) 
135          vars.push_back(var);
136    }
137
138    if (lps)
139    {
140       localVar *var = lps->findLocalVar(name);
141       if (var) 
142          vars.push_back(var);
143    }
144
145    if (vars.size() > origSize)
146       return true;
147
148    return false;
149 }
150
151 bool Function::getLocalVariables(std::vector<localVar *> &vars)
152 {
153    module_->exec()->parseTypesNow();    
154
155    localVarCollection *lvs = NULL;
156    if (!getAnnotation(lvs, FunctionLocalVariablesAnno))
157    {
158       return false;
159    }
160    if (!lvs)
161    {
162       fprintf(stderr, "%s[%d]:  FIXME:  NULL ptr for annotation\n", FILE__, __LINE__);
163       return false;
164    }
165
166 #if 0 
167    fprintf(stderr, "%s[%d]:  FIXME here: localVarCollection = %p\n", FILE__, __LINE__, lvs);
168    std::vector<localVar *> * v  = new std::vector<localVar *>();
169    vars = *v;
170    return true;
171 #else
172    vars = *(lvs->getAllVars());
173
174    if (vars.size())
175       return true;
176 #endif
177
178    fprintf(stderr, "%s[%d]:  NO LOCAL VARS\n", FILE__, __LINE__);
179    return false;
180 }
181
182 bool Function::getParams(std::vector<localVar *> &params)
183 {
184    module_->exec()->parseTypesNow();    
185
186    localVarCollection *lvs = NULL;
187    if (!getAnnotation(lvs, FunctionParametersAnno))
188    {
189       return false;
190    }
191
192    if (!lvs)
193    {
194       fprintf(stderr, "%s[%d]:  FIXME:  NULL ptr for annotation\n", FILE__, __LINE__);
195       return false;
196    }
197
198    params = *(lvs->getAllVars());
199
200    if (params.size())
201       return true;
202    return false;
203 }
204
205 bool Function::addLocalVar(localVar *locVar)
206 {
207    localVarCollection *lvs = NULL;
208
209    if (!getAnnotation(lvs, FunctionLocalVariablesAnno))
210    {
211       lvs = new localVarCollection();
212
213       if (!addAnnotation(lvs, FunctionLocalVariablesAnno))
214       {
215          fprintf(stderr, "%s[%d]:  failed to add local var collecton anno\n", 
216                FILE__, __LINE__);
217          return false;
218       }
219    }
220
221    lvs->addLocalVar(locVar);
222    return true;
223 }
224
225 bool Function::addParam(localVar *param)
226 {
227         localVarCollection *ps = NULL;
228
229         if (!getAnnotation(ps, FunctionParametersAnno))
230         {
231                 ps = new localVarCollection();
232
233                 if (!addAnnotation(ps, FunctionParametersAnno))
234                 {
235                         fprintf(stderr, "%s[%d]:  failed to add local var collecton anno\n", 
236                                         FILE__, __LINE__);
237                         return false;
238                 }
239         }
240
241         ps->addLocalVar(param);
242
243         return true;
244 }
245
246 Function::~Function()
247 {
248    localVarCollection *lvs = NULL;
249    if (getAnnotation(lvs, FunctionLocalVariablesAnno) && (NULL != lvs))
250    {
251            if (!removeAnnotation(FunctionLocalVariablesAnno))
252            {
253                    fprintf(stderr, "%s[%d]:  ERROR removing local vars\n", FILE__, __LINE__);
254            }
255            delete lvs;
256    }
257
258    localVarCollection *lps = NULL;
259    if (getAnnotation(lps, FunctionParametersAnno) && (NULL != lps))
260    {
261            if (!removeAnnotation(FunctionParametersAnno))
262            {
263                    fprintf(stderr, "%s[%d]:  ERROR removing params\n", FILE__, __LINE__);
264            }
265            delete lps;
266    }
267
268 }
269
270 Serializable *Function::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
271 {
272         if (!sb) SER_ERR("bad paramater sb");
273
274
275
276         //  Use typeID as unique identifier
277         unsigned int t_id = retType_ ? retType_->getID() : (unsigned int) 0xdeadbeef;
278
279                 ifxml_start_element(sb, tag);
280                 gtranslate(sb, t_id, "typeID");
281                 gtranslate(sb, framePtrRegNum_, "framePointerRegister");
282 #if 0
283                 gtranslate(sb, locs_, "framePointerLocationList");
284 #endif
285                 Aggregate::serialize_aggregate(sb);
286                 ifxml_end_element(sb, tag);
287                 if (sb->isInput())
288                 {
289                         if (t_id == 0xdeadbeef)
290                                 retType_ = NULL;
291                         else
292                                 restore_type_by_id(sb, retType_, t_id);
293 #if 0
294                         for (unsigned long i = 0; i < symbols_.size(); ++i)
295                         {
296                                 symbols_[i]->setFunction(this);
297                                 assert(symbols_[i]->isFunction());
298                         }
299 #endif
300                 }
301
302         serialize_printf("%s[%d]:  Function(%p--%s)::%s\n", FILE__, __LINE__, this,
303                         getAllPrettyNames().size() ? getAllPrettyNames()[0].c_str() : "UNNAMED_FUNCTION",
304                         sb->isInput() ? "deserialize" : "serialize");
305         return NULL;
306 }
307
308 bool Function::removeSymbol(Symbol *sym) 
309 {
310         removeSymbolInt(sym);
311         if (symbols_.empty()) {
312                 module_->exec()->deleteFunction(this);
313         }
314         return true;
315 }
316
317 std::ostream &operator<<(std::ostream &os, const Dyninst::SymtabAPI::VariableLocation &l)
318 {
319         const char *stc = storageClass2Str(l.stClass);
320         const char *strc = storageRefClass2Str(l.refClass);
321         os << "{"
322                 << "storageClass=" << stc
323                 << " storageRefClass=" << strc
324                 << " reg=" << l.reg
325                 << " frameOffset=" << l.frameOffset
326                 << " lowPC=" << l.lowPC
327                 << " hiPC=" << l.hiPC
328                 << "}";
329         return os;
330 }
331
332 std::ostream &operator<<(std::ostream &os, const Dyninst::SymtabAPI::Function &f)
333 {
334         std::string tname(f.retType_ ? f.retType_->getName() : "no_type");
335         const Aggregate *ag = dynamic_cast<const Aggregate *>(&f);
336         assert(ag);
337
338         os  << "Function{"
339                 << " type=" << tname
340                 << " framePtrRegNum_=" << f.framePtrRegNum_
341                 << " FramePtrLocationList=[";
342 #if 0
343         for (unsigned int i = 0; i < f.locs_.size(); ++i)
344         {
345                 os << f.locs_[i]; 
346                 if ( (i + 1) < f.locs_.size())
347                         os << ", ";
348         }
349 #endif
350         os  << "] ";
351         os  <<  *ag;
352         os  <<  "}";
353         return os;
354
355 }
356
357 bool Function::operator==(const Function &f)
358 {
359         if (retType_ && !f.retType_)
360                 return false;
361         if (!retType_ && f.retType_)
362                 return false;
363         if (retType_)
364                 if (retType_->getID() != f.retType_->getID())
365                 {
366                         return false;
367                 }
368
369         if (framePtrRegNum_ != f.framePtrRegNum_)
370                 return false;
371
372 #if 0
373         if (locs_.size() != f.locs_.size())
374                 return false;
375
376         for (unsigned int i = 0; i < locs_.size(); ++i)
377         {
378                 if (locs_[i] == locs_[i])
379                         return false;
380         }
381 #endif
382
383         return ((Aggregate &)(*this)) == ((Aggregate &)f);
384 }
385